blob: daa3e1faca92ebca4d0e70d010b2ef901d86e1e4 [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.
#ifndef _VPN_MANAGER_IPSEC_MANAGER_H_
#define _VPN_MANAGER_IPSEC_MANAGER_H_
#include <string>
#include <sys/socket.h>
#include "base/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/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();
// 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);
virtual bool Start();
virtual void Stop();
virtual int Poll();
virtual void ProcessOutput();
virtual bool IsChild(pid_t pid);
virtual void OnSyslogOutput(const std::string& prefix,
const std::string& line);
// Returns the stderr output file descriptor of our child process.
int output_fd() const { return output_fd_; }
private:
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);
// 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.
scoped_ptr<Daemon> starter_daemon_;
// IPsec charon daemon.
scoped_ptr<Daemon> charon_daemon_;
};
} // namespace vpn_manager
#endif // _VPN_MANAGER_IPSEC_MANAGER_H_