text: // Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #ifndef VPN_MANAGER_IPSEC_MANAGER_H_
  #define VPN_MANAGER_IPSEC_MANAGER_H_
  
  #include <sys/socket.h>
  
  #include <memory>
  #include <string>
  
  #include <base/files/file_path.h>
  #include <base/time/time.h>
  #include <gtest/gtest_prod.h>  // for FRIEND_TEST
  
  #include "vpn-manager/service_manager.h"
  
  namespace vpn_manager {
  
  class Daemon;
  
  // Manages the ipsec daemon.  This manager orchestrates configuring and
  // launching the strongswan starter process which in turn launches the
  // charon daemon.
  class IpsecManager : public ServiceManager {
   public:
    IpsecManager(const std::string& esp,
                 const std::string& ike,
                 int ipsec_timeout,
                 const std::string& left_protoport,
                 bool rekey,
                 const std::string& right_protoport,
                 const std::string& tunnel_group,
                 const std::string& type,
                 const base::FilePath& temp_path,
                 const base::FilePath& persistent_path);
    ~IpsecManager() override = default;
  
    // Initialize the object to control IKE version |ike_version| daemon,
    // connecting to the given |remote_address|, with given paths to
    // pre-shared key file |psk_file|, server certificate authority file
    // |server_ca_file|, client key file |client_key_file|, and client
    // certificate file |client_cert_file|.
    bool Initialize(int ike_version,
                    const sockaddr_storage& remote_address,
                    const std::string& psk_file,
                    const std::string& xauth_credentials_file,
                    const std::string& server_ca_file,
                    const std::string& server_id,
                    const std::string& client_cert_tpm_slot,
                    const std::string& client_cert_tpm_id,
                    const std::string& tpm_user_pin);
  
    bool Start() override;
    void Stop() override;
    int Poll() override;
    void ProcessOutput() override;
    bool IsChild(pid_t pid) override;
    void OnSyslogOutput(const std::string& prefix,
                        const std::string& line) override;
  
    // Returns the stderr output file descriptor of our child process.
    int output_fd() const { return output_fd_; }
  
   private:
    friend class IpsecManagerTest;
    friend class IpsecManagerFuzzer;
    FRIEND_TEST(IpsecManagerTest, CreateIpsecRunDirectory);
    FRIEND_TEST(IpsecManagerTest, PollWaitIfNotUpYet);
    FRIEND_TEST(IpsecManagerTest, PollTimeoutWaiting);
    FRIEND_TEST(IpsecManagerTest, PollTransitionToUp);
    FRIEND_TEST(IpsecManagerTest, PollNothingIfRunning);
    FRIEND_TEST(IpsecManagerTest, FormatSecretsNoSlot);
    FRIEND_TEST(IpsecManagerTest, FormatSecretsNonZeroSlot);
    FRIEND_TEST(IpsecManagerTest, FormatSecretsXauthCredentials);
    FRIEND_TEST(IpsecManagerTest, FormatStrongswanConfigFile);
    FRIEND_TEST(IpsecManagerTest, StartStarter);
    FRIEND_TEST(IpsecManagerTestIkeV1Psk, FormatSecrets);
    FRIEND_TEST(IpsecManagerTestIkeV1Psk, FormatStarterConfigFile);
    FRIEND_TEST(IpsecManagerTestIkeV1Psk, GetAddressesFromRemoteHost);
    FRIEND_TEST(IpsecManagerTestIkeV1Psk, Start);
    FRIEND_TEST(IpsecManagerTestIkeV1Psk, WriteConfigFiles);
    FRIEND_TEST(IpsecManagerTestIkeV1Certs, FormatSecrets);
    FRIEND_TEST(IpsecManagerTestIkeV1Certs, FormatStarterConfigFile);
    FRIEND_TEST(IpsecManagerTestIkeV1Certs, WriteConfigFiles);
    FRIEND_TEST(IpsecManagerTestBogusCerts, FormatStarterConfigFile);
  
    bool ReadCertificateSubject(const base::FilePath& filepath,
                                std::string* output);
    bool FormatIpsecSecret(std::string* formatted);
    bool FormatXauthSecret(std::string* formatted);
    bool FormatSecrets(std::string* formatted);
    void KillCurrentlyRunning();
    bool WriteConfigFile(const std::string& output_name,
                         const std::string& contents);
    bool MakeSymbolicLink(const std::string& output_name,
                          const base::FilePath& source_path);
    bool WriteConfigFiles();
    bool CreateIpsecRunDirectory();
    std::string FormatStrongswanConfigFile();
    std::string FormatStarterConfigFile();
    bool StartStarter();
  
    // Command line flags.
    std::string esp_;
    std::string ike_;
    int ipsec_timeout_;
    std::string left_protoport_;
    bool rekey_;
    std::string right_protoport_;
    std::string tunnel_group_;
    std::string type_;
  
    // for testing, always return these values from
    // GetAddressesFromRemoteHostname.
    const char* force_local_address_;
    // ipsec daemon stderr pipe file descriptor.
    int output_fd_;
    // IKE key exchange version to use.
    int ike_version_;
    // Writeable directory that the root filesystem has symbolic links to for
    // all VPN configuration files we care about.
    base::FilePath persistent_path_;
    // File whose existence signifies ipsec is now up.
    std::string ipsec_up_file_;
    // String with which to prefix ipsec output log lines.
    std::string ipsec_prefix_;
    // Remote address of IPsec connection.
    sockaddr_storage remote_address_;
    // Remote address of IPsec connection (as a string).
    std::string remote_address_text_;
    // File containing the IPsec pre-shared key.
    std::string psk_file_;
    // File containing the server certificate authority in DER format.
    std::string server_ca_file_;
    // Subject of the server certificate authority certificate.
    std::string server_ca_subject_;
    // ID that server must send to identify itself.
    std::string server_id_;
    // PKCS#11 slot containing the client certificate.
    std::string client_cert_slot_;
    // PKCS#11 object id of the client certificate.
    std::string client_cert_id_;
    // PKCS#11 user PIN needed to get the client certificate.
    std::string user_pin_;
    // Last partial line read from output_fd_.
    std::string partial_output_line_;
    // File containing the XAUTH username and password.
    std::string xauth_credentials_file_;
    // File containing the XAUTH username gained from FormatSecrets().
    std::string xauth_identity_;
    // Time when ipsec was started.
    base::TimeTicks start_ticks_;
    // IPsec starter daemon.
    std::unique_ptr<Daemon> starter_daemon_;
    // IPsec charon daemon.
    std::unique_ptr<Daemon> charon_daemon_;
  };
  
  }  // namespace vpn_manager
  
  #endif  // VPN_MANAGER_IPSEC_MANAGER_H_
  