blob: 7de16b0d14d51627b7933c9fb46c5af4af6114fb [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
5#include "shill/l2tp_ipsec_driver.h"
6
Darin Petkovf7ef50a2012-04-16 20:54:31 +02007#include <base/file_util.h>
Paul Stewart5ad16062013-02-21 18:10:48 -08008#include <base/files/scoped_temp_dir.h>
mukesh agrawalae30e9e2013-05-28 14:09:16 -07009#include <base/memory/weak_ptr.h>
Darin Petkov209e6292012-04-20 11:33:32 +020010#include <base/string_util.h>
Darin Petkov85d53172013-03-13 16:43:28 +010011#include <chromeos/vpn-manager/service_error.h>
Darin Petkov7476a262012-04-12 16:30:46 +020012#include <gtest/gtest.h>
13
14#include "shill/event_dispatcher.h"
15#include "shill/nice_mock_control.h"
Darin Petkov209e6292012-04-20 11:33:32 +020016#include "shill/mock_adaptors.h"
Paul Stewart5baebb72013-03-14 11:43:29 -070017#include "shill/mock_certificate_file.h"
Darin Petkov0e9735d2012-04-24 12:33:45 +020018#include "shill/mock_device_info.h"
mukesh agrawalae30e9e2013-05-28 14:09:16 -070019#include "shill/mock_external_task.h"
Darin Petkov7476a262012-04-12 16:30:46 +020020#include "shill/mock_glib.h"
21#include "shill/mock_manager.h"
22#include "shill/mock_metrics.h"
Darin Petkovf7ef50a2012-04-16 20:54:31 +020023#include "shill/mock_nss.h"
mukesh agrawal9da07772013-05-15 14:15:17 -070024#include "shill/mock_ppp_device.h"
Darin Petkov7476a262012-04-12 16:30:46 +020025#include "shill/mock_vpn_service.h"
26
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080027using base::FilePath;
Darin Petkovf7ef50a2012-04-16 20:54:31 +020028using std::find;
Darin Petkov209e6292012-04-20 11:33:32 +020029using std::map;
Darin Petkovf7ef50a2012-04-16 20:54:31 +020030using std::string;
31using std::vector;
32using testing::_;
33using testing::ElementsAreArray;
mukesh agrawalae30e9e2013-05-28 14:09:16 -070034using testing::Mock;
Darin Petkov0e9735d2012-04-24 12:33:45 +020035using testing::NiceMock;
Darin Petkovf7ef50a2012-04-16 20:54:31 +020036using testing::Return;
37using testing::ReturnRef;
Darin Petkov209e6292012-04-20 11:33:32 +020038using testing::SetArgumentPointee;
Darin Petkov0e9735d2012-04-24 12:33:45 +020039using testing::StrictMock;
Darin Petkovf7ef50a2012-04-16 20:54:31 +020040
Darin Petkov7476a262012-04-12 16:30:46 +020041namespace shill {
42
Darin Petkov209e6292012-04-20 11:33:32 +020043class L2TPIPSecDriverTest : public testing::Test,
44 public RPCTaskDelegate {
Darin Petkov7476a262012-04-12 16:30:46 +020045 public:
46 L2TPIPSecDriverTest()
Darin Petkov0e9735d2012-04-24 12:33:45 +020047 : device_info_(&control_, &dispatcher_, &metrics_, &manager_),
Thieu Le6c1e3bb2013-02-06 15:20:35 -080048 metrics_(&dispatcher_),
Darin Petkov0e9735d2012-04-24 12:33:45 +020049 manager_(&control_, &dispatcher_, &metrics_, &glib_),
Darin Petkovf8046b82012-04-24 16:29:23 +020050 driver_(new L2TPIPSecDriver(&control_, &dispatcher_, &metrics_,
51 &manager_, &device_info_, &glib_)),
Darin Petkov7476a262012-04-12 16:30:46 +020052 service_(new MockVPNService(&control_, &dispatcher_, &metrics_,
Darin Petkovf8046b82012-04-24 16:29:23 +020053 &manager_, driver_)),
mukesh agrawal9da07772013-05-15 14:15:17 -070054 device_(new MockPPPDevice(&control_, &dispatcher_, &metrics_, &manager_,
55 kInterfaceName, kInterfaceIndex)),
Paul Stewart5baebb72013-03-14 11:43:29 -070056 certificate_file_(new MockCertificateFile()),
mukesh agrawalae30e9e2013-05-28 14:09:16 -070057 weak_ptr_factory_(this) {
Darin Petkovf7ef50a2012-04-16 20:54:31 +020058 driver_->nss_ = &nss_;
Paul Stewart5baebb72013-03-14 11:43:29 -070059 driver_->certificate_file_.reset(certificate_file_); // Passes ownership.
Darin Petkovf7ef50a2012-04-16 20:54:31 +020060 }
Darin Petkov7476a262012-04-12 16:30:46 +020061
62 virtual ~L2TPIPSecDriverTest() {}
63
Darin Petkovf7ef50a2012-04-16 20:54:31 +020064 virtual void SetUp() {
65 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
66 }
67
68 virtual void TearDown() {
Darin Petkovf8046b82012-04-24 16:29:23 +020069 driver_->device_ = NULL;
Darin Petkov209e6292012-04-20 11:33:32 +020070 driver_->service_ = NULL;
Darin Petkovf7ef50a2012-04-16 20:54:31 +020071 ASSERT_TRUE(temp_dir_.Delete());
72 }
73
Darin Petkov7476a262012-04-12 16:30:46 +020074 protected:
Darin Petkovf8046b82012-04-24 16:29:23 +020075 static const char kInterfaceName[];
76 static const int kInterfaceIndex;
77
Darin Petkovf7ef50a2012-04-16 20:54:31 +020078 void SetArg(const string &arg, const string &value) {
Darin Petkov01c66042012-04-26 11:10:45 +020079 driver_->args()->SetString(arg, value);
Darin Petkovf7ef50a2012-04-16 20:54:31 +020080 }
81
Paul Stewarteb713e82013-06-28 14:51:54 -070082 void SetArgArray(const string &arg, const vector<string> &value) {
83 driver_->args()->SetStrings(arg, value);
84 }
85
Darin Petkovd4325392012-04-23 15:48:22 +020086 KeyValueStore *GetArgs() {
87 return driver_->args();
88 }
89
Darin Petkova42afe32013-02-05 16:53:52 +010090 string GetProviderType() {
91 return driver_->GetProviderType();
92 }
93
mukesh agrawal9da07772013-05-15 14:15:17 -070094 void SetDevice(const PPPDeviceRefPtr &device) {
Darin Petkov0cd0d1e2013-02-11 12:49:10 +010095 driver_->device_ = device;
96 }
97
Darin Petkova42afe32013-02-05 16:53:52 +010098 void SetService(const VPNServiceRefPtr &service) {
99 driver_->service_ = service;
100 }
101
102 VPNServiceRefPtr GetService() {
103 return driver_->service_;
104 }
105
106 void OnConnectTimeout() {
107 driver_->OnConnectTimeout();
108 }
109
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100110 void StartConnectTimeout(int timeout_seconds) {
111 driver_->StartConnectTimeout(timeout_seconds);
Darin Petkova42afe32013-02-05 16:53:52 +0100112 }
113
114 bool IsConnectTimeoutStarted() {
115 return driver_->IsConnectTimeoutStarted();
116 }
117
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200118 // Used to assert that a flag appears in the options.
119 void ExpectInFlags(const vector<string> &options, const string &flag,
120 const string &value);
121
Darin Petkov0e9735d2012-04-24 12:33:45 +0200122 FilePath SetupPSKFile();
123
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100124 FilePath GetPSKFile() { return driver_->psk_file_; }
125
126 void InvokeNotify(const string &reason, const map<string, string> &dict) {
127 driver_->Notify(reason, dict);
128 }
129
Darin Petkov209e6292012-04-20 11:33:32 +0200130 // Inherited from RPCTaskDelegate.
131 virtual void GetLogin(string *user, string *password);
132 virtual void Notify(const string &reason, const map<string, string> &dict);
133
Paul Stewart5ad16062013-02-21 18:10:48 -0800134 base::ScopedTempDir temp_dir_;
Darin Petkov7476a262012-04-12 16:30:46 +0200135 NiceMockControl control_;
Darin Petkov0e9735d2012-04-24 12:33:45 +0200136 NiceMock<MockDeviceInfo> device_info_;
Darin Petkov7476a262012-04-12 16:30:46 +0200137 EventDispatcher dispatcher_;
138 MockMetrics metrics_;
139 MockGLib glib_;
140 MockManager manager_;
141 L2TPIPSecDriver *driver_; // Owned by |service_|.
142 scoped_refptr<MockVPNService> service_;
mukesh agrawal9da07772013-05-15 14:15:17 -0700143 scoped_refptr<MockPPPDevice> device_;
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200144 MockNSS nss_;
Paul Stewart5baebb72013-03-14 11:43:29 -0700145 MockCertificateFile *certificate_file_; // Owned by |driver_|.
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700146 base::WeakPtrFactory<L2TPIPSecDriverTest> weak_ptr_factory_;
Darin Petkov7476a262012-04-12 16:30:46 +0200147};
148
Darin Petkovf8046b82012-04-24 16:29:23 +0200149const char L2TPIPSecDriverTest::kInterfaceName[] = "ppp0";
150const int L2TPIPSecDriverTest::kInterfaceIndex = 123;
151
Darin Petkov209e6292012-04-20 11:33:32 +0200152void L2TPIPSecDriverTest::GetLogin(string */*user*/, string */*password*/) {}
153
154void L2TPIPSecDriverTest::Notify(
155 const string &/*reason*/, const map<string, string> &/*dict*/) {}
156
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200157void L2TPIPSecDriverTest::ExpectInFlags(
158 const vector<string> &options, const string &flag, const string &value) {
159 vector<string>::const_iterator it =
160 find(options.begin(), options.end(), flag);
161
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700162 ASSERT_TRUE(it != options.end()); // Don't crash below.
163 EXPECT_EQ(flag, *it);
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200164 it++;
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700165 ASSERT_TRUE(it != options.end()); // Don't crash below.
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200166 EXPECT_EQ(value, *it);
167}
168
Darin Petkov0e9735d2012-04-24 12:33:45 +0200169FilePath L2TPIPSecDriverTest::SetupPSKFile() {
170 FilePath psk_file;
171 EXPECT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(), &psk_file));
172 EXPECT_FALSE(psk_file.empty());
173 EXPECT_TRUE(file_util::PathExists(psk_file));
174 driver_->psk_file_ = psk_file;
175 return psk_file;
176}
177
Darin Petkov7476a262012-04-12 16:30:46 +0200178TEST_F(L2TPIPSecDriverTest, GetProviderType) {
Darin Petkova42afe32013-02-05 16:53:52 +0100179 EXPECT_EQ(flimflam::kProviderL2tpIpsec, GetProviderType());
Darin Petkov7476a262012-04-12 16:30:46 +0200180}
181
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200182TEST_F(L2TPIPSecDriverTest, Cleanup) {
Darin Petkov85d53172013-03-13 16:43:28 +0100183 driver_->IdleService(); // Ensure no crash.
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200184
Darin Petkova0e645e2012-04-25 11:38:59 +0200185 driver_->device_ = device_;
Darin Petkov209e6292012-04-20 11:33:32 +0200186 driver_->service_ = service_;
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700187 driver_->external_task_.reset(
188 new MockExternalTask(&control_,
189 &glib_,
190 weak_ptr_factory_.GetWeakPtr(),
191 base::Callback<void(pid_t, int)>()));
mukesh agrawal9da07772013-05-15 14:15:17 -0700192 EXPECT_CALL(*device_, DropConnection());
Darin Petkova0e645e2012-04-25 11:38:59 +0200193 EXPECT_CALL(*device_, SetEnabled(false));
Darin Petkov85d53172013-03-13 16:43:28 +0100194 EXPECT_CALL(*service_, SetFailure(Service::kFailureBadPassphrase));
Darin Petkov0e9735d2012-04-24 12:33:45 +0200195 FilePath psk_file = SetupPSKFile();
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100196 StartConnectTimeout(0);
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700197 driver_->FailService(Service::kFailureBadPassphrase); // Trigger Cleanup.
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200198 EXPECT_FALSE(file_util::PathExists(psk_file));
199 EXPECT_TRUE(driver_->psk_file_.empty());
Darin Petkova0e645e2012-04-25 11:38:59 +0200200 EXPECT_FALSE(driver_->device_);
Darin Petkov209e6292012-04-20 11:33:32 +0200201 EXPECT_FALSE(driver_->service_);
Darin Petkov602303f2012-06-06 12:15:59 +0200202 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700203 EXPECT_FALSE(driver_->external_task_);
Darin Petkov85d53172013-03-13 16:43:28 +0100204
205 driver_->service_ = service_;
206 EXPECT_CALL(*service_, SetState(Service::kStateIdle));
207 driver_->IdleService();
208 EXPECT_FALSE(driver_->service_);
Darin Petkov209e6292012-04-20 11:33:32 +0200209}
210
Darin Petkov0e9735d2012-04-24 12:33:45 +0200211TEST_F(L2TPIPSecDriverTest, DeletePSKFile) {
212 FilePath psk_file = SetupPSKFile();
213 driver_->DeletePSKFile();
214 EXPECT_FALSE(file_util::PathExists(psk_file));
215 EXPECT_TRUE(driver_->psk_file_.empty());
216}
217
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200218TEST_F(L2TPIPSecDriverTest, InitOptionsNoHost) {
219 Error error;
220 vector<string> options;
Darin Petkov209e6292012-04-20 11:33:32 +0200221 EXPECT_FALSE(driver_->InitOptions(&options, &error));
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200222 EXPECT_EQ(Error::kInvalidArguments, error.type());
223 EXPECT_TRUE(options.empty());
224}
225
226TEST_F(L2TPIPSecDriverTest, InitOptions) {
227 static const char kHost[] = "192.168.2.254";
228 static const char kCaCertNSS[] = "{1234}";
229 static const char kPSK[] = "foobar";
230
231 SetArg(flimflam::kProviderHostProperty, kHost);
232 SetArg(flimflam::kL2tpIpsecCaCertNssProperty, kCaCertNSS);
233 SetArg(flimflam::kL2tpIpsecPskProperty, kPSK);
234
235 FilePath empty_cert;
236 EXPECT_CALL(nss_, GetDERCertfile(kCaCertNSS, _)).WillOnce(Return(empty_cert));
237
238 const FilePath temp_dir(temp_dir_.path());
239 EXPECT_CALL(manager_, run_path()).WillOnce(ReturnRef(temp_dir));
240
241 Error error;
242 vector<string> options;
Darin Petkov209e6292012-04-20 11:33:32 +0200243 EXPECT_TRUE(driver_->InitOptions(&options, &error));
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200244 EXPECT_TRUE(error.IsSuccess());
245
246 ExpectInFlags(options, "--remote_host", kHost);
247 ASSERT_FALSE(driver_->psk_file_.empty());
248 ExpectInFlags(options, "--psk_file", driver_->psk_file_.value());
249}
250
251TEST_F(L2TPIPSecDriverTest, InitPSKOptions) {
252 Error error;
253 vector<string> options;
254 static const char kPSK[] = "foobar";
255 const FilePath bad_dir("/non/existent/directory");
256 const FilePath temp_dir(temp_dir_.path());
257 EXPECT_CALL(manager_, run_path())
258 .WillOnce(ReturnRef(bad_dir))
259 .WillOnce(ReturnRef(temp_dir));
260
261 EXPECT_TRUE(driver_->InitPSKOptions(&options, &error));
262 EXPECT_TRUE(options.empty());
263 EXPECT_TRUE(error.IsSuccess());
264
265 SetArg(flimflam::kL2tpIpsecPskProperty, kPSK);
266
267 EXPECT_FALSE(driver_->InitPSKOptions(&options, &error));
268 EXPECT_TRUE(options.empty());
269 EXPECT_EQ(Error::kInternalError, error.type());
270 error.Reset();
271
272 EXPECT_TRUE(driver_->InitPSKOptions(&options, &error));
273 ASSERT_FALSE(driver_->psk_file_.empty());
274 ExpectInFlags(options, "--psk_file", driver_->psk_file_.value());
275 EXPECT_TRUE(error.IsSuccess());
276 string contents;
277 EXPECT_TRUE(
278 file_util::ReadFileToString(driver_->psk_file_, &contents));
279 EXPECT_EQ(kPSK, contents);
280 struct stat buf;
281 ASSERT_EQ(0, stat(driver_->psk_file_.value().c_str(), &buf));
282 EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR, buf.st_mode);
283}
284
285TEST_F(L2TPIPSecDriverTest, InitNSSOptions) {
286 static const char kHost[] = "192.168.2.254";
287 static const char kCaCertNSS[] = "{1234}";
288 static const char kNSSCertfile[] = "/tmp/nss-cert";
289 FilePath empty_cert;
290 FilePath nss_cert(kNSSCertfile);
291 SetArg(flimflam::kProviderHostProperty, kHost);
292 SetArg(flimflam::kL2tpIpsecCaCertNssProperty, kCaCertNSS);
293 EXPECT_CALL(nss_,
294 GetDERCertfile(kCaCertNSS,
295 ElementsAreArray(kHost, arraysize(kHost) - 1)))
296 .WillOnce(Return(empty_cert))
297 .WillOnce(Return(nss_cert));
298
299 vector<string> options;
300 driver_->InitNSSOptions(&options);
301 EXPECT_TRUE(options.empty());
302 driver_->InitNSSOptions(&options);
303 ExpectInFlags(options, "--server_ca_file", kNSSCertfile);
304}
305
Paul Stewart5baebb72013-03-14 11:43:29 -0700306TEST_F(L2TPIPSecDriverTest, InitPEMOptions) {
Paul Stewarteb713e82013-06-28 14:51:54 -0700307 const vector<string> kCaCertPEM{ "Insert PEM encoded data here" };
Paul Stewart5baebb72013-03-14 11:43:29 -0700308 static const char kPEMCertfile[] = "/tmp/der-file-from-pem-cert";
309 FilePath empty_cert;
310 FilePath pem_cert(kPEMCertfile);
Paul Stewarteb713e82013-06-28 14:51:54 -0700311 SetArgArray(kL2tpIpsecCaCertPemProperty, kCaCertPEM);
312 EXPECT_CALL(*certificate_file_, CreatePEMFromStrings(kCaCertPEM))
Paul Stewart5baebb72013-03-14 11:43:29 -0700313 .WillOnce(Return(empty_cert))
314 .WillOnce(Return(pem_cert));
315
316 vector<string> options;
317 driver_->InitPEMOptions(&options);
318 EXPECT_TRUE(options.empty());
319 driver_->InitPEMOptions(&options);
320 ExpectInFlags(options, "--server_ca_file", kPEMCertfile);
321}
322
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200323TEST_F(L2TPIPSecDriverTest, AppendValueOption) {
324 static const char kOption[] = "--l2tpipsec-option";
325 static const char kProperty[] = "L2TPIPSec.SomeProperty";
326 static const char kValue[] = "some-property-value";
327 static const char kOption2[] = "--l2tpipsec-option2";
328 static const char kProperty2[] = "L2TPIPSec.SomeProperty2";
329 static const char kValue2[] = "some-property-value2";
330
331 vector<string> options;
332 EXPECT_FALSE(
333 driver_->AppendValueOption(
334 "L2TPIPSec.UnknownProperty", kOption, &options));
335 EXPECT_TRUE(options.empty());
336
337 SetArg(kProperty, "");
338 EXPECT_FALSE(driver_->AppendValueOption(kProperty, kOption, &options));
339 EXPECT_TRUE(options.empty());
340
341 SetArg(kProperty, kValue);
342 SetArg(kProperty2, kValue2);
343 EXPECT_TRUE(driver_->AppendValueOption(kProperty, kOption, &options));
344 EXPECT_TRUE(driver_->AppendValueOption(kProperty2, kOption2, &options));
345 EXPECT_EQ(4, options.size());
346 EXPECT_EQ(kOption, options[0]);
347 EXPECT_EQ(kValue, options[1]);
348 EXPECT_EQ(kOption2, options[2]);
349 EXPECT_EQ(kValue2, options[3]);
350}
351
352TEST_F(L2TPIPSecDriverTest, AppendFlag) {
353 static const char kTrueOption[] = "--l2tpipsec-option";
354 static const char kFalseOption[] = "--nol2tpipsec-option";
355 static const char kProperty[] = "L2TPIPSec.SomeProperty";
356 static const char kTrueOption2[] = "--l2tpipsec-option2";
357 static const char kFalseOption2[] = "--nol2tpipsec-option2";
358 static const char kProperty2[] = "L2TPIPSec.SomeProperty2";
359
360 vector<string> options;
361 EXPECT_FALSE(driver_->AppendFlag("L2TPIPSec.UnknownProperty",
362 kTrueOption, kFalseOption, &options));
363 EXPECT_TRUE(options.empty());
364
365 SetArg(kProperty, "");
366 EXPECT_FALSE(
367 driver_->AppendFlag(kProperty, kTrueOption, kFalseOption, &options));
368 EXPECT_TRUE(options.empty());
369
370 SetArg(kProperty, "true");
371 SetArg(kProperty2, "false");
372 EXPECT_TRUE(
373 driver_->AppendFlag(kProperty, kTrueOption, kFalseOption, &options));
374 EXPECT_TRUE(
375 driver_->AppendFlag(kProperty2, kTrueOption2, kFalseOption2, &options));
376 EXPECT_EQ(2, options.size());
377 EXPECT_EQ(kTrueOption, options[0]);
378 EXPECT_EQ(kFalseOption2, options[1]);
379}
380
Darin Petkov209e6292012-04-20 11:33:32 +0200381TEST_F(L2TPIPSecDriverTest, GetLogin) {
382 static const char kUser[] = "joesmith";
383 static const char kPassword[] = "random-password";
384 string user, password;
385 SetArg(flimflam::kL2tpIpsecUserProperty, kUser);
386 driver_->GetLogin(&user, &password);
387 EXPECT_TRUE(user.empty());
388 EXPECT_TRUE(password.empty());
389 SetArg(flimflam::kL2tpIpsecUserProperty, "");
390 SetArg(flimflam::kL2tpIpsecPasswordProperty, kPassword);
391 driver_->GetLogin(&user, &password);
392 EXPECT_TRUE(user.empty());
393 EXPECT_TRUE(password.empty());
394 SetArg(flimflam::kL2tpIpsecUserProperty, kUser);
395 driver_->GetLogin(&user, &password);
396 EXPECT_EQ(kUser, user);
397 EXPECT_EQ(kPassword, password);
398}
399
400TEST_F(L2TPIPSecDriverTest, OnL2TPIPSecVPNDied) {
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700401 const int kPID = 123456;
Darin Petkov85d53172013-03-13 16:43:28 +0100402 driver_->service_ = service_;
403 EXPECT_CALL(*service_, SetFailure(Service::kFailureDNSLookup));
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700404 driver_->OnL2TPIPSecVPNDied(
405 kPID, vpn_manager::kServiceErrorResolveHostnameFailed << 8);
Darin Petkov85d53172013-03-13 16:43:28 +0100406 EXPECT_FALSE(driver_->service_);
Darin Petkov209e6292012-04-20 11:33:32 +0200407}
408
Darin Petkov209e6292012-04-20 11:33:32 +0200409TEST_F(L2TPIPSecDriverTest, SpawnL2TPIPSecVPN) {
410 Error error;
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700411 // Fail without sufficient arguments.
Darin Petkov209e6292012-04-20 11:33:32 +0200412 EXPECT_FALSE(driver_->SpawnL2TPIPSecVPN(&error));
413 EXPECT_TRUE(error.IsFailure());
414
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700415 // Provide the required arguments.
Darin Petkov209e6292012-04-20 11:33:32 +0200416 static const char kHost[] = "192.168.2.254";
417 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkov209e6292012-04-20 11:33:32 +0200418
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700419 // TODO(quiche): Instead of setting expectations based on what
420 // ExternalTask will call, mock out ExternalTask. Non-trivial,
421 // though, because ExternalTask is constructed during the
422 // call to driver_->Connect.
423 EXPECT_CALL(glib_, SpawnAsync(_, _, _, _, _, _, _, _)).
424 WillOnce(Return(false)).
425 WillOnce(Return(true));
426 EXPECT_CALL(glib_, ChildWatchAdd(_, _, _));
427
Darin Petkov209e6292012-04-20 11:33:32 +0200428 EXPECT_FALSE(driver_->SpawnL2TPIPSecVPN(&error));
Darin Petkov209e6292012-04-20 11:33:32 +0200429 EXPECT_TRUE(driver_->SpawnL2TPIPSecVPN(&error));
Darin Petkov209e6292012-04-20 11:33:32 +0200430}
431
432TEST_F(L2TPIPSecDriverTest, Connect) {
433 EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
434 static const char kHost[] = "192.168.2.254";
435 SetArg(flimflam::kProviderHostProperty, kHost);
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700436
437 // TODO(quiche): Instead of setting expectations based on what
438 // ExternalTask will call, mock out ExternalTask. Non-trivial,
439 // though, because ExternalTask is constructed during the
440 // call to driver_->Connect.
Darin Petkov68710d72013-02-13 14:22:56 +0100441 EXPECT_CALL(glib_, SpawnAsync(_, _, _, _, _, _, _, _)).WillOnce(Return(true));
Darin Petkov209e6292012-04-20 11:33:32 +0200442 EXPECT_CALL(glib_, ChildWatchAdd(_, _, _)).WillOnce(Return(1));
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700443
Darin Petkov209e6292012-04-20 11:33:32 +0200444 Error error;
445 driver_->Connect(service_, &error);
446 EXPECT_TRUE(error.IsSuccess());
Darin Petkov602303f2012-06-06 12:15:59 +0200447 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov209e6292012-04-20 11:33:32 +0200448}
449
Darin Petkova0e645e2012-04-25 11:38:59 +0200450TEST_F(L2TPIPSecDriverTest, Disconnect) {
451 driver_->device_ = device_;
452 driver_->service_ = service_;
mukesh agrawal9da07772013-05-15 14:15:17 -0700453 EXPECT_CALL(*device_, DropConnection());
Darin Petkova0e645e2012-04-25 11:38:59 +0200454 EXPECT_CALL(*device_, SetEnabled(false));
455 EXPECT_CALL(*service_, SetState(Service::kStateIdle));
456 driver_->Disconnect();
457 EXPECT_FALSE(driver_->device_);
458 EXPECT_FALSE(driver_->service_);
459}
460
Darin Petkov5eb05422012-05-11 15:45:25 +0200461TEST_F(L2TPIPSecDriverTest, OnConnectionDisconnected) {
462 driver_->service_ = service_;
Darin Petkova42afe32013-02-05 16:53:52 +0100463 EXPECT_CALL(*service_, SetState(Service::kStateIdle));
Darin Petkov5eb05422012-05-11 15:45:25 +0200464 driver_->OnConnectionDisconnected();
465 EXPECT_FALSE(driver_->service_);
466}
467
Darin Petkova42afe32013-02-05 16:53:52 +0100468TEST_F(L2TPIPSecDriverTest, OnConnectTimeout) {
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100469 StartConnectTimeout(0);
Darin Petkova42afe32013-02-05 16:53:52 +0100470 SetService(service_);
Darin Petkov85d53172013-03-13 16:43:28 +0100471 EXPECT_CALL(*service_, SetFailure(Service::kFailureConnect));
Darin Petkova42afe32013-02-05 16:53:52 +0100472 OnConnectTimeout();
473 EXPECT_FALSE(GetService());
474 EXPECT_FALSE(IsConnectTimeoutStarted());
475}
476
Darin Petkovd4325392012-04-23 15:48:22 +0200477TEST_F(L2TPIPSecDriverTest, InitPropertyStore) {
478 // Sanity test property store initialization.
479 PropertyStore store;
480 driver_->InitPropertyStore(&store);
481 const string kUser = "joe";
482 Error error;
483 EXPECT_TRUE(
484 store.SetStringProperty(flimflam::kL2tpIpsecUserProperty, kUser, &error));
485 EXPECT_TRUE(error.IsSuccess());
Darin Petkovb536a742012-04-26 11:31:28 +0200486 EXPECT_EQ(kUser,
487 GetArgs()->LookupString(flimflam::kL2tpIpsecUserProperty, ""));
488}
489
490TEST_F(L2TPIPSecDriverTest, GetProvider) {
491 PropertyStore store;
492 driver_->InitPropertyStore(&store);
493 {
Darin Petkovb536a742012-04-26 11:31:28 +0200494 KeyValueStore props;
Paul Stewarte6e8e492013-01-17 11:00:50 -0800495 Error error;
Darin Petkov4682aa82012-05-31 16:24:11 +0200496 EXPECT_TRUE(
Paul Stewarte6e8e492013-01-17 11:00:50 -0800497 store.GetKeyValueStoreProperty(
498 flimflam::kProviderProperty, &props, &error));
Darin Petkovb536a742012-04-26 11:31:28 +0200499 EXPECT_TRUE(props.LookupBool(flimflam::kPassphraseRequiredProperty, false));
500 EXPECT_TRUE(
501 props.LookupBool(flimflam::kL2tpIpsecPskRequiredProperty, false));
502 }
503 {
Darin Petkovb536a742012-04-26 11:31:28 +0200504 KeyValueStore props;
505 SetArg(flimflam::kL2tpIpsecPasswordProperty, "random-password");
506 SetArg(flimflam::kL2tpIpsecPskProperty, "random-psk");
Paul Stewarte6e8e492013-01-17 11:00:50 -0800507 Error error;
Darin Petkov4682aa82012-05-31 16:24:11 +0200508 EXPECT_TRUE(
Paul Stewarte6e8e492013-01-17 11:00:50 -0800509 store.GetKeyValueStoreProperty(
510 flimflam::kProviderProperty, &props, &error));
Darin Petkovb536a742012-04-26 11:31:28 +0200511 EXPECT_FALSE(props.LookupBool(flimflam::kPassphraseRequiredProperty, true));
512 EXPECT_FALSE(
513 props.LookupBool(flimflam::kL2tpIpsecPskRequiredProperty, true));
Darin Petkov02236552012-06-11 13:15:19 +0200514 EXPECT_FALSE(props.ContainsString(flimflam::kL2tpIpsecPasswordProperty));
Darin Petkovb536a742012-04-26 11:31:28 +0200515 }
Darin Petkovd4325392012-04-23 15:48:22 +0200516}
517
Darin Petkov0e9735d2012-04-24 12:33:45 +0200518namespace {
519MATCHER_P(IsIPAddress, address, "") {
520 IPAddress ip_address(IPAddress::kFamilyIPv4);
521 EXPECT_TRUE(ip_address.SetAddressFromString(address));
522 return ip_address.Equals(arg);
523}
524} // namespace
525
526TEST_F(L2TPIPSecDriverTest, Notify) {
527 map<string, string> config;
mukesh agrawal9da07772013-05-15 14:15:17 -0700528 config[kPPPInterfaceName] = kInterfaceName;
Darin Petkovf8046b82012-04-24 16:29:23 +0200529 EXPECT_CALL(device_info_, GetIndex(kInterfaceName))
530 .WillOnce(Return(kInterfaceIndex));
Darin Petkovf8046b82012-04-24 16:29:23 +0200531 EXPECT_CALL(*device_, SetEnabled(true));
532 EXPECT_CALL(*device_, UpdateIPConfig(_));
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100533 SetDevice(device_);
Darin Petkov0e9735d2012-04-24 12:33:45 +0200534 FilePath psk_file = SetupPSKFile();
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100535 StartConnectTimeout(0);
Paul Stewart91a43cb2013-03-02 21:34:15 -0800536
537 EXPECT_CALL(metrics_, SendEnumToUMA(
538 Metrics::kMetricVpnDriver,
539 Metrics::kVpnDriverL2tpIpsec,
540 Metrics::kMetricVpnDriverMax));
541 EXPECT_CALL(metrics_, SendEnumToUMA(
542 Metrics::kMetricVpnRemoteAuthenticationType,
543 Metrics::kVpnRemoteAuthenticationTypeL2tpIpsecPsk,
544 Metrics::kVpnRemoteAuthenticationTypeMax));
545 EXPECT_CALL(metrics_, SendEnumToUMA(
546 Metrics::kMetricVpnUserAuthenticationType,
547 Metrics::kVpnUserAuthenticationTypeL2tpIpsecUsernamePassword,
548 Metrics::kVpnUserAuthenticationTypeMax));
549
550 Error unused_error;
551 PropertyStore store;
552 driver_->InitPropertyStore(&store);
Paul Stewarte8e71da2013-03-20 08:48:33 -0700553 store.SetStringProperty(flimflam::kL2tpIpsecPskProperty, "x", &unused_error);
554 store.SetStringProperty(flimflam::kL2tpIpsecPasswordProperty, "y",
Paul Stewart91a43cb2013-03-02 21:34:15 -0800555 &unused_error);
556
mukesh agrawal9da07772013-05-15 14:15:17 -0700557 InvokeNotify(kPPPReasonConnect, config);
Darin Petkov0e9735d2012-04-24 12:33:45 +0200558 EXPECT_FALSE(file_util::PathExists(psk_file));
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100559 EXPECT_TRUE(GetPSKFile().empty());
560 EXPECT_FALSE(IsConnectTimeoutStarted());
Darin Petkov0e9735d2012-04-24 12:33:45 +0200561}
562
Darin Petkov69990222012-11-14 09:25:25 +0100563TEST_F(L2TPIPSecDriverTest, NotifyDisconnected) {
Darin Petkova0e645e2012-04-25 11:38:59 +0200564 map<string, string> dict;
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700565 base::Callback<void(pid_t, int)> death_callback;
566 MockExternalTask *local_external_task =
567 new MockExternalTask(&control_, &glib_, weak_ptr_factory_.GetWeakPtr(),
568 death_callback);
Darin Petkova0e645e2012-04-25 11:38:59 +0200569 driver_->device_ = device_;
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700570 driver_->external_task_.reset(local_external_task); // passes ownership
mukesh agrawal9da07772013-05-15 14:15:17 -0700571 EXPECT_CALL(*device_, DropConnection());
Darin Petkov69990222012-11-14 09:25:25 +0100572 EXPECT_CALL(*device_, SetEnabled(false));
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700573 EXPECT_CALL(*local_external_task, OnDelete())
574 .Times(0); // Not until event loop.
mukesh agrawal9da07772013-05-15 14:15:17 -0700575 driver_->Notify(kPPPReasonDisconnect, dict);
Darin Petkov69990222012-11-14 09:25:25 +0100576 EXPECT_FALSE(driver_->device_);
mukesh agrawalae30e9e2013-05-28 14:09:16 -0700577 EXPECT_FALSE(driver_->external_task_.get());
578 Mock::VerifyAndClearExpectations(local_external_task);
579
580 EXPECT_CALL(*local_external_task, OnDelete());
Darin Petkov69990222012-11-14 09:25:25 +0100581 dispatcher_.PostTask(MessageLoop::QuitClosure());
582 dispatcher_.DispatchForever();
Darin Petkova0e645e2012-04-25 11:38:59 +0200583}
584
585TEST_F(L2TPIPSecDriverTest, VerifyPaths) {
586 // Ensure that the various path constants that the L2TP/IPSec driver uses
587 // actually exists in the build image. Due to build dependencies, they should
588 // already exist by the time we run unit tests.
589
590 // The L2TPIPSecDriver path constants are absolute. FilePath::Append asserts
591 // that its argument is not an absolute path, so we need to strip the leading
592 // separators. There's nothing built into FilePath to do so.
593 static const char *kPaths[] = {
594 L2TPIPSecDriver::kL2TPIPSecVPNPath,
mukesh agrawal9da07772013-05-15 14:15:17 -0700595 PPPDevice::kPluginPath,
Darin Petkova0e645e2012-04-25 11:38:59 +0200596 };
597 for (size_t i = 0; i < arraysize(kPaths); i++) {
598 string path(kPaths[i]);
599 TrimString(path, FilePath::kSeparators, &path);
600 EXPECT_TRUE(file_util::PathExists(FilePath(SYSROOT).Append(path)))
601 << kPaths[i];
602 }
603}
604
Darin Petkov7476a262012-04-12 16:30:46 +0200605} // namespace shill