blob: 1c69892a12287b774f98825b7877044bda3cf577 [file] [log] [blame]
// 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.
#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 {
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);
~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 struct sockaddr& 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_; }
friend class IpsecManagerTest;
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);
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();
bool SetIpsecGroup(const base::FilePath& file_path);
// 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_;
const char* force_remote_address_;
// ipsec daemon stderr pipe file descriptor.
int output_fd_;
// IKE key exchange version to use.
int ike_version_;
// Group id of the "ipsec" group on this machine. This is the group
// that we expect the underlying IKE daemons to run as.
gid_t ipsec_group_;
// Writeable directory that the root filesystem has symbolic links to for
// all VPN configuration files we care about.
base::FilePath persistent_path_;
// Directory containing run files for ipsec that we create with
// permissions locked to ipsec group.
std::string ipsec_run_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_;
// File containing starter process's process id.
std::string starter_pid_file_;
// File containing charon process's process id.
std::string charon_pid_file_;
// Remote address of IPsec connection.
struct sockaddr 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