blob: ffbe05c889490afe90acee27bbb3535866ae48c5 [file] [log] [blame]
Darin Petkov7476a262012-04-12 16:30:46 +02001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Darin Petkova42afe32013-02-05 16:53:52 +01005#ifndef SHILL_L2TP_IPSEC_DRIVER_H_
6#define SHILL_L2TP_IPSEC_DRIVER_H_
Darin Petkov7476a262012-04-12 16:30:46 +02007
Darin Petkovf7ef50a2012-04-16 20:54:31 +02008#include <vector>
9
10#include <base/file_path.h>
Darin Petkov209e6292012-04-20 11:33:32 +020011#include <base/memory/scoped_ptr.h>
Darin Petkovf7ef50a2012-04-16 20:54:31 +020012#include <gtest/gtest_prod.h> // for FRIEND_TEST
13
Darin Petkov209e6292012-04-20 11:33:32 +020014#include "shill/glib.h"
Darin Petkov0e9735d2012-04-24 12:33:45 +020015#include "shill/ipconfig.h"
Darin Petkov209e6292012-04-20 11:33:32 +020016#include "shill/rpc_task.h"
17#include "shill/service.h"
Darin Petkov7476a262012-04-12 16:30:46 +020018#include "shill/vpn_driver.h"
19
20namespace shill {
21
Darin Petkov95f317f2012-10-22 13:37:43 +020022// Declared in the header to avoid linking unused code into shims.
23static const char kL2TPIPSecDNS1[] = "DNS1";
24static const char kL2TPIPSecDNS2[] = "DNS2";
25static const char kL2TPIPSecExternalIP4Address[] = "EXTERNAL_IP4_ADDRESS";
26static const char kL2TPIPSecGatewayAddress[] = "GATEWAY_ADDRESS";
27static const char kL2TPIPSecInterfaceName[] = "INTERNAL_IFNAME";
28static const char kL2TPIPSecInternalIP4Address[] = "INTERNAL_IP4_ADDRESS";
29static const char kL2TPIPSecLNSAddress[] = "LNS_ADDRESS";
30static const char kL2TPIPSecReasonConnect[] = "connect";
31static const char kL2TPIPSecReasonDisconnect[] = "disconnect";
32
Paul Stewart5baebb72013-03-14 11:43:29 -070033class CertificateFile;
Darin Petkov209e6292012-04-20 11:33:32 +020034class ControlInterface;
Darin Petkovf8046b82012-04-24 16:29:23 +020035class DeviceInfo;
Darin Petkov209e6292012-04-20 11:33:32 +020036class GLib;
Darin Petkovf8046b82012-04-24 16:29:23 +020037class Metrics;
Darin Petkovf7ef50a2012-04-16 20:54:31 +020038class NSS;
Darin Petkov5a850472012-06-06 15:44:24 +020039class ProcessKiller;
Darin Petkovf7ef50a2012-04-16 20:54:31 +020040
Darin Petkov209e6292012-04-20 11:33:32 +020041class L2TPIPSecDriver : public VPNDriver,
42 public RPCTaskDelegate {
Darin Petkov7476a262012-04-12 16:30:46 +020043 public:
Darin Petkovf8046b82012-04-24 16:29:23 +020044 L2TPIPSecDriver(ControlInterface *control,
45 EventDispatcher *dispatcher,
46 Metrics *metrics,
47 Manager *manager,
48 DeviceInfo *device_info,
49 GLib *glib);
Darin Petkov7476a262012-04-12 16:30:46 +020050 virtual ~L2TPIPSecDriver();
51
Darin Petkova42afe32013-02-05 16:53:52 +010052 protected:
Darin Petkov7476a262012-04-12 16:30:46 +020053 // Inherited from VPNDriver.
54 virtual bool ClaimInterface(const std::string &link_name,
55 int interface_index);
56 virtual void Connect(const VPNServiceRefPtr &service, Error *error);
57 virtual void Disconnect();
Darin Petkov7476a262012-04-12 16:30:46 +020058 virtual std::string GetProviderType() const;
Darin Petkova42afe32013-02-05 16:53:52 +010059 virtual void OnConnectionDisconnected();
60 virtual void OnConnectTimeout();
Darin Petkov7476a262012-04-12 16:30:46 +020061
62 private:
63 friend class L2TPIPSecDriverTest;
Darin Petkovf7ef50a2012-04-16 20:54:31 +020064 FRIEND_TEST(L2TPIPSecDriverTest, AppendFlag);
65 FRIEND_TEST(L2TPIPSecDriverTest, AppendValueOption);
66 FRIEND_TEST(L2TPIPSecDriverTest, Cleanup);
Darin Petkov602303f2012-06-06 12:15:59 +020067 FRIEND_TEST(L2TPIPSecDriverTest, Connect);
Darin Petkov0e9735d2012-04-24 12:33:45 +020068 FRIEND_TEST(L2TPIPSecDriverTest, DeletePSKFile);
Darin Petkova0e645e2012-04-25 11:38:59 +020069 FRIEND_TEST(L2TPIPSecDriverTest, Disconnect);
Darin Petkov209e6292012-04-20 11:33:32 +020070 FRIEND_TEST(L2TPIPSecDriverTest, GetLogin);
71 FRIEND_TEST(L2TPIPSecDriverTest, InitEnvironment);
Darin Petkovf7ef50a2012-04-16 20:54:31 +020072 FRIEND_TEST(L2TPIPSecDriverTest, InitNSSOptions);
Paul Stewart5baebb72013-03-14 11:43:29 -070073 FRIEND_TEST(L2TPIPSecDriverTest, InitPEMOptions);
Darin Petkovf7ef50a2012-04-16 20:54:31 +020074 FRIEND_TEST(L2TPIPSecDriverTest, InitOptions);
75 FRIEND_TEST(L2TPIPSecDriverTest, InitOptionsNoHost);
76 FRIEND_TEST(L2TPIPSecDriverTest, InitPSKOptions);
Darin Petkov69990222012-11-14 09:25:25 +010077 FRIEND_TEST(L2TPIPSecDriverTest, NotifyDisconnected);
Darin Petkov5eb05422012-05-11 15:45:25 +020078 FRIEND_TEST(L2TPIPSecDriverTest, OnConnectionDisconnected);
Darin Petkov209e6292012-04-20 11:33:32 +020079 FRIEND_TEST(L2TPIPSecDriverTest, OnL2TPIPSecVPNDied);
Darin Petkov0e9735d2012-04-24 12:33:45 +020080 FRIEND_TEST(L2TPIPSecDriverTest, ParseIPConfiguration);
Darin Petkov209e6292012-04-20 11:33:32 +020081 FRIEND_TEST(L2TPIPSecDriverTest, SpawnL2TPIPSecVPN);
Darin Petkova0e645e2012-04-25 11:38:59 +020082 FRIEND_TEST(L2TPIPSecDriverTest, VerifyPaths);
Darin Petkovd4325392012-04-23 15:48:22 +020083
Darin Petkovf7ef50a2012-04-16 20:54:31 +020084 static const char kPPPDPlugin[];
Darin Petkov209e6292012-04-20 11:33:32 +020085 static const char kL2TPIPSecVPNPath[];
Darin Petkovd4325392012-04-23 15:48:22 +020086 static const Property kProperties[];
Darin Petkovf7ef50a2012-04-16 20:54:31 +020087
Darin Petkov209e6292012-04-20 11:33:32 +020088 bool SpawnL2TPIPSecVPN(Error *error);
89
90 void InitEnvironment(std::vector<std::string> *environment);
91
92 bool InitOptions(std::vector<std::string> *options, Error *error);
Darin Petkovf7ef50a2012-04-16 20:54:31 +020093 bool InitPSKOptions(std::vector<std::string> *options, Error *error);
94 void InitNSSOptions(std::vector<std::string> *options);
Paul Stewart5baebb72013-03-14 11:43:29 -070095 bool InitPEMOptions(std::vector<std::string> *options);
Darin Petkovf7ef50a2012-04-16 20:54:31 +020096
Darin Petkov85d53172013-03-13 16:43:28 +010097 // Resets the VPN state and deallocates all resources. If there's a service
98 // associated through Connect, sets its state to Service::kStateIdle and
99 // disassociates from the service.
100 void IdleService();
101
102 // Resets the VPN state and deallocates all resources. If there's a service
103 // associated through Connect, sets its state to Service::kStateFailure with
104 // failure reason |failure| and disassociates from the service.
105 void FailService(Service::ConnectFailure failure);
106
107 // Implements the IdleService and FailService methods. Resets the VPN state
108 // and deallocates all resources. If there's a service associated through
109 // Connect, sets its state |state|; if |state| is Service::kStateFailure, sets
110 // the failure reason to |failure|; disassociates from the service.
111 void Cleanup(Service::ConnectState state, Service::ConnectFailure failure);
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200112
Darin Petkov0e9735d2012-04-24 12:33:45 +0200113 void DeletePSKFile();
114
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200115 // Returns true if an opton was appended.
116 bool AppendValueOption(const std::string &property,
117 const std::string &option,
118 std::vector<std::string> *options);
119
120 // Returns true if a flag was appended.
121 bool AppendFlag(const std::string &property,
122 const std::string &true_option,
123 const std::string &false_option,
124 std::vector<std::string> *options);
125
Darin Petkov0e9735d2012-04-24 12:33:45 +0200126 static void ParseIPConfiguration(
127 const std::map<std::string, std::string> &configuration,
128 IPConfig::Properties *properties,
129 std::string *interface_name);
130
Darin Petkov209e6292012-04-20 11:33:32 +0200131 // Called when the l2tpipsec_vpn process exits.
132 static void OnL2TPIPSecVPNDied(GPid pid, gint status, gpointer data);
133
Darin Petkov85d53172013-03-13 16:43:28 +0100134 static Service::ConnectFailure TranslateExitStatusToFailure(int status);
135
Darin Petkovb536a742012-04-26 11:31:28 +0200136 // Inherit from VPNDriver to add custom properties.
137 virtual KeyValueStore GetProvider(Error *error);
138
Darin Petkov209e6292012-04-20 11:33:32 +0200139 // Implements RPCTaskDelegate.
140 virtual void GetLogin(std::string *user, std::string *password);
141 virtual void Notify(const std::string &reason,
142 const std::map<std::string, std::string> &dict);
143
Darin Petkov69990222012-11-14 09:25:25 +0100144 static void DeleteRPCTask(RPCTask *rpc_task);
145
Paul Stewart91a43cb2013-03-02 21:34:15 -0800146 void ReportConnectionMetrics();
147
Darin Petkov209e6292012-04-20 11:33:32 +0200148 ControlInterface *control_;
Darin Petkovf8046b82012-04-24 16:29:23 +0200149 Metrics *metrics_;
150 DeviceInfo *device_info_;
Darin Petkov209e6292012-04-20 11:33:32 +0200151 GLib *glib_;
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200152 NSS *nss_;
Darin Petkov5a850472012-06-06 15:44:24 +0200153 ProcessKiller *process_killer_;
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200154
Darin Petkov209e6292012-04-20 11:33:32 +0200155 VPNServiceRefPtr service_;
156 scoped_ptr<RPCTask> rpc_task_;
Albert Chaulk0e1cdea2013-02-27 15:32:55 -0800157 base::FilePath psk_file_;
Paul Stewart5baebb72013-03-14 11:43:29 -0700158 scoped_ptr<CertificateFile> certificate_file_;
Darin Petkovf8046b82012-04-24 16:29:23 +0200159 VPNRefPtr device_;
Darin Petkov7476a262012-04-12 16:30:46 +0200160
Darin Petkov209e6292012-04-20 11:33:32 +0200161 // The PID of the spawned l2tpipsec_vpn process. May be 0 if no process has
162 // been spawned yet or the process has died.
163 int pid_;
164
165 // Child exit watch callback source tag.
166 unsigned int child_watch_tag_;
167
Darin Petkov7476a262012-04-12 16:30:46 +0200168 DISALLOW_COPY_AND_ASSIGN(L2TPIPSecDriver);
169};
170
171} // namespace shill
172
Darin Petkova42afe32013-02-05 16:53:52 +0100173#endif // SHILL_L2TP_IPSEC_DRIVER_H_