blob: 1cd364177010bb43b3d861c10de69d3aa9ce2ac7 [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>
Darin Petkov209e6292012-04-20 11:33:32 +02009#include <base/string_util.h>
Darin Petkov85d53172013-03-13 16:43:28 +010010#include <chromeos/vpn-manager/service_error.h>
Darin Petkov7476a262012-04-12 16:30:46 +020011#include <gtest/gtest.h>
12
13#include "shill/event_dispatcher.h"
14#include "shill/nice_mock_control.h"
Darin Petkov209e6292012-04-20 11:33:32 +020015#include "shill/mock_adaptors.h"
Paul Stewart5baebb72013-03-14 11:43:29 -070016#include "shill/mock_certificate_file.h"
Darin Petkov0e9735d2012-04-24 12:33:45 +020017#include "shill/mock_device_info.h"
Darin Petkov7476a262012-04-12 16:30:46 +020018#include "shill/mock_glib.h"
19#include "shill/mock_manager.h"
20#include "shill/mock_metrics.h"
Darin Petkovf7ef50a2012-04-16 20:54:31 +020021#include "shill/mock_nss.h"
Darin Petkov5a850472012-06-06 15:44:24 +020022#include "shill/mock_process_killer.h"
Darin Petkovf8046b82012-04-24 16:29:23 +020023#include "shill/mock_vpn.h"
Darin Petkov7476a262012-04-12 16:30:46 +020024#include "shill/mock_vpn_service.h"
Darin Petkovf8046b82012-04-24 16:29:23 +020025#include "shill/vpn.h"
Darin Petkov7476a262012-04-12 16:30:46 +020026
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;
Darin Petkov0e9735d2012-04-24 12:33:45 +020034using testing::NiceMock;
Darin Petkovf7ef50a2012-04-16 20:54:31 +020035using testing::Return;
36using testing::ReturnRef;
Darin Petkov209e6292012-04-20 11:33:32 +020037using testing::SetArgumentPointee;
Darin Petkov0e9735d2012-04-24 12:33:45 +020038using testing::StrictMock;
Darin Petkovf7ef50a2012-04-16 20:54:31 +020039
Darin Petkov7476a262012-04-12 16:30:46 +020040namespace shill {
41
Darin Petkov209e6292012-04-20 11:33:32 +020042class L2TPIPSecDriverTest : public testing::Test,
43 public RPCTaskDelegate {
Darin Petkov7476a262012-04-12 16:30:46 +020044 public:
45 L2TPIPSecDriverTest()
Darin Petkov0e9735d2012-04-24 12:33:45 +020046 : device_info_(&control_, &dispatcher_, &metrics_, &manager_),
Thieu Le6c1e3bb2013-02-06 15:20:35 -080047 metrics_(&dispatcher_),
Darin Petkov0e9735d2012-04-24 12:33:45 +020048 manager_(&control_, &dispatcher_, &metrics_, &glib_),
Darin Petkovf8046b82012-04-24 16:29:23 +020049 driver_(new L2TPIPSecDriver(&control_, &dispatcher_, &metrics_,
50 &manager_, &device_info_, &glib_)),
Darin Petkov7476a262012-04-12 16:30:46 +020051 service_(new MockVPNService(&control_, &dispatcher_, &metrics_,
Darin Petkovf8046b82012-04-24 16:29:23 +020052 &manager_, driver_)),
53 device_(new MockVPN(&control_, &dispatcher_, &metrics_, &manager_,
Darin Petkov69990222012-11-14 09:25:25 +010054 kInterfaceName, kInterfaceIndex)),
Paul Stewart5baebb72013-03-14 11:43:29 -070055 certificate_file_(new MockCertificateFile()),
Darin Petkov69990222012-11-14 09:25:25 +010056 test_rpc_task_destroyed_(false) {
Darin Petkovf7ef50a2012-04-16 20:54:31 +020057 driver_->nss_ = &nss_;
Paul Stewart5baebb72013-03-14 11:43:29 -070058 driver_->certificate_file_.reset(certificate_file_); // Passes ownership.
Darin Petkov5a850472012-06-06 15:44:24 +020059 driver_->process_killer_ = &process_killer_;
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 Petkov209e6292012-04-20 11:33:32 +020069 driver_->child_watch_tag_ = 0;
70 driver_->pid_ = 0;
Darin Petkovf8046b82012-04-24 16:29:23 +020071 driver_->device_ = NULL;
Darin Petkov209e6292012-04-20 11:33:32 +020072 driver_->service_ = NULL;
Darin Petkovf7ef50a2012-04-16 20:54:31 +020073 ASSERT_TRUE(temp_dir_.Delete());
74 }
75
Darin Petkov69990222012-11-14 09:25:25 +010076 void set_test_rpc_task_destroyed(bool destroyed) {
77 test_rpc_task_destroyed_ = destroyed;
78 }
79
Darin Petkov7476a262012-04-12 16:30:46 +020080 protected:
Darin Petkovf8046b82012-04-24 16:29:23 +020081 static const char kInterfaceName[];
82 static const int kInterfaceIndex;
83
Darin Petkovf7ef50a2012-04-16 20:54:31 +020084 void SetArg(const string &arg, const string &value) {
Darin Petkov01c66042012-04-26 11:10:45 +020085 driver_->args()->SetString(arg, value);
Darin Petkovf7ef50a2012-04-16 20:54:31 +020086 }
87
Darin Petkovd4325392012-04-23 15:48:22 +020088 KeyValueStore *GetArgs() {
89 return driver_->args();
90 }
91
Darin Petkova42afe32013-02-05 16:53:52 +010092 string GetProviderType() {
93 return driver_->GetProviderType();
94 }
95
Darin Petkov0cd0d1e2013-02-11 12:49:10 +010096 void SetDevice(const VPNRefPtr &device) {
97 driver_->device_ = device;
98 }
99
Darin Petkova42afe32013-02-05 16:53:52 +0100100 void SetService(const VPNServiceRefPtr &service) {
101 driver_->service_ = service;
102 }
103
104 VPNServiceRefPtr GetService() {
105 return driver_->service_;
106 }
107
108 void OnConnectTimeout() {
109 driver_->OnConnectTimeout();
110 }
111
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100112 void StartConnectTimeout(int timeout_seconds) {
113 driver_->StartConnectTimeout(timeout_seconds);
Darin Petkova42afe32013-02-05 16:53:52 +0100114 }
115
116 bool IsConnectTimeoutStarted() {
117 return driver_->IsConnectTimeoutStarted();
118 }
119
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200120 // Used to assert that a flag appears in the options.
121 void ExpectInFlags(const vector<string> &options, const string &flag,
122 const string &value);
123
Darin Petkov0e9735d2012-04-24 12:33:45 +0200124 FilePath SetupPSKFile();
125
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100126 FilePath GetPSKFile() { return driver_->psk_file_; }
127
128 void InvokeNotify(const string &reason, const map<string, string> &dict) {
129 driver_->Notify(reason, dict);
130 }
131
Darin Petkov209e6292012-04-20 11:33:32 +0200132 // Inherited from RPCTaskDelegate.
133 virtual void GetLogin(string *user, string *password);
134 virtual void Notify(const string &reason, const map<string, string> &dict);
135
Paul Stewart5ad16062013-02-21 18:10:48 -0800136 base::ScopedTempDir temp_dir_;
Darin Petkov7476a262012-04-12 16:30:46 +0200137 NiceMockControl control_;
Darin Petkov0e9735d2012-04-24 12:33:45 +0200138 NiceMock<MockDeviceInfo> device_info_;
Darin Petkov7476a262012-04-12 16:30:46 +0200139 EventDispatcher dispatcher_;
140 MockMetrics metrics_;
141 MockGLib glib_;
142 MockManager manager_;
143 L2TPIPSecDriver *driver_; // Owned by |service_|.
144 scoped_refptr<MockVPNService> service_;
Darin Petkovf8046b82012-04-24 16:29:23 +0200145 scoped_refptr<MockVPN> device_;
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200146 MockNSS nss_;
Paul Stewart5baebb72013-03-14 11:43:29 -0700147 MockCertificateFile *certificate_file_; // Owned by |driver_|.
Darin Petkov5a850472012-06-06 15:44:24 +0200148 MockProcessKiller process_killer_;
Darin Petkov69990222012-11-14 09:25:25 +0100149 bool test_rpc_task_destroyed_;
Darin Petkov7476a262012-04-12 16:30:46 +0200150};
151
Darin Petkov69990222012-11-14 09:25:25 +0100152namespace {
153
154class TestRPCTask : public RPCTask {
155 public:
156 TestRPCTask(ControlInterface *control, L2TPIPSecDriverTest *test);
157 virtual ~TestRPCTask();
158
159 private:
160 L2TPIPSecDriverTest *test_;
161};
162
163TestRPCTask::TestRPCTask(ControlInterface *control, L2TPIPSecDriverTest *test)
164 : RPCTask(control, test),
165 test_(test) {
166 test_->set_test_rpc_task_destroyed(false);
167}
168
169TestRPCTask::~TestRPCTask() {
170 test_->set_test_rpc_task_destroyed(true);
171 test_ = NULL;
172}
173
174} // namespace
175
Darin Petkovf8046b82012-04-24 16:29:23 +0200176const char L2TPIPSecDriverTest::kInterfaceName[] = "ppp0";
177const int L2TPIPSecDriverTest::kInterfaceIndex = 123;
178
Darin Petkov209e6292012-04-20 11:33:32 +0200179void L2TPIPSecDriverTest::GetLogin(string */*user*/, string */*password*/) {}
180
181void L2TPIPSecDriverTest::Notify(
182 const string &/*reason*/, const map<string, string> &/*dict*/) {}
183
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200184void L2TPIPSecDriverTest::ExpectInFlags(
185 const vector<string> &options, const string &flag, const string &value) {
186 vector<string>::const_iterator it =
187 find(options.begin(), options.end(), flag);
188
189 EXPECT_TRUE(it != options.end());
190 if (it != options.end())
191 return; // Don't crash below.
192 it++;
193 EXPECT_TRUE(it != options.end());
194 if (it != options.end())
195 return; // Don't crash below.
196 EXPECT_EQ(value, *it);
197}
198
Darin Petkov0e9735d2012-04-24 12:33:45 +0200199FilePath L2TPIPSecDriverTest::SetupPSKFile() {
200 FilePath psk_file;
201 EXPECT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(), &psk_file));
202 EXPECT_FALSE(psk_file.empty());
203 EXPECT_TRUE(file_util::PathExists(psk_file));
204 driver_->psk_file_ = psk_file;
205 return psk_file;
206}
207
Darin Petkov7476a262012-04-12 16:30:46 +0200208TEST_F(L2TPIPSecDriverTest, GetProviderType) {
Darin Petkova42afe32013-02-05 16:53:52 +0100209 EXPECT_EQ(flimflam::kProviderL2tpIpsec, GetProviderType());
Darin Petkov7476a262012-04-12 16:30:46 +0200210}
211
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200212TEST_F(L2TPIPSecDriverTest, Cleanup) {
Darin Petkov85d53172013-03-13 16:43:28 +0100213 driver_->IdleService(); // Ensure no crash.
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200214
Darin Petkov209e6292012-04-20 11:33:32 +0200215 const unsigned int kTag = 123;
216 driver_->child_watch_tag_ = kTag;
217 EXPECT_CALL(glib_, SourceRemove(kTag));
218 const int kPID = 123456;
219 driver_->pid_ = kPID;
Darin Petkov5a850472012-06-06 15:44:24 +0200220 EXPECT_CALL(process_killer_, Kill(kPID, _));
Darin Petkova0e645e2012-04-25 11:38:59 +0200221 driver_->device_ = device_;
Darin Petkov209e6292012-04-20 11:33:32 +0200222 driver_->service_ = service_;
Darin Petkova0e645e2012-04-25 11:38:59 +0200223 EXPECT_CALL(*device_, OnDisconnected());
224 EXPECT_CALL(*device_, SetEnabled(false));
Darin Petkov85d53172013-03-13 16:43:28 +0100225 EXPECT_CALL(*service_, SetFailure(Service::kFailureBadPassphrase));
Darin Petkov209e6292012-04-20 11:33:32 +0200226 driver_->rpc_task_.reset(new RPCTask(&control_, this));
Darin Petkov0e9735d2012-04-24 12:33:45 +0200227 FilePath psk_file = SetupPSKFile();
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100228 StartConnectTimeout(0);
Darin Petkov85d53172013-03-13 16:43:28 +0100229 driver_->FailService(Service::kFailureBadPassphrase);
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200230 EXPECT_FALSE(file_util::PathExists(psk_file));
231 EXPECT_TRUE(driver_->psk_file_.empty());
Darin Petkov209e6292012-04-20 11:33:32 +0200232 EXPECT_EQ(0, driver_->child_watch_tag_);
233 EXPECT_EQ(0, driver_->pid_);
234 EXPECT_FALSE(driver_->rpc_task_.get());
Darin Petkova0e645e2012-04-25 11:38:59 +0200235 EXPECT_FALSE(driver_->device_);
Darin Petkov209e6292012-04-20 11:33:32 +0200236 EXPECT_FALSE(driver_->service_);
Darin Petkov602303f2012-06-06 12:15:59 +0200237 EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
Darin Petkov85d53172013-03-13 16:43:28 +0100238
239 driver_->service_ = service_;
240 EXPECT_CALL(*service_, SetState(Service::kStateIdle));
241 driver_->IdleService();
242 EXPECT_FALSE(driver_->service_);
Darin Petkov209e6292012-04-20 11:33:32 +0200243}
244
Darin Petkov0e9735d2012-04-24 12:33:45 +0200245TEST_F(L2TPIPSecDriverTest, DeletePSKFile) {
246 FilePath psk_file = SetupPSKFile();
247 driver_->DeletePSKFile();
248 EXPECT_FALSE(file_util::PathExists(psk_file));
249 EXPECT_TRUE(driver_->psk_file_.empty());
250}
251
Darin Petkov209e6292012-04-20 11:33:32 +0200252TEST_F(L2TPIPSecDriverTest, InitEnvironment) {
253 vector<string> env;
254 driver_->rpc_task_.reset(new RPCTask(&control_, this));
255 driver_->InitEnvironment(&env);
Darin Petkov95f317f2012-10-22 13:37:43 +0200256 ASSERT_EQ(2, env.size());
257 EXPECT_EQ(
258 string(kRPCTaskServiceVariable) + "=" + RPCTaskMockAdaptor::kRpcConnId,
259 env[0]);
260 EXPECT_EQ(string(kRPCTaskPathVariable) + "=" + RPCTaskMockAdaptor::kRpcId,
Darin Petkov209e6292012-04-20 11:33:32 +0200261 env[1]);
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200262}
263
264TEST_F(L2TPIPSecDriverTest, InitOptionsNoHost) {
265 Error error;
266 vector<string> options;
Darin Petkov209e6292012-04-20 11:33:32 +0200267 EXPECT_FALSE(driver_->InitOptions(&options, &error));
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200268 EXPECT_EQ(Error::kInvalidArguments, error.type());
269 EXPECT_TRUE(options.empty());
270}
271
272TEST_F(L2TPIPSecDriverTest, InitOptions) {
273 static const char kHost[] = "192.168.2.254";
274 static const char kCaCertNSS[] = "{1234}";
275 static const char kPSK[] = "foobar";
276
277 SetArg(flimflam::kProviderHostProperty, kHost);
278 SetArg(flimflam::kL2tpIpsecCaCertNssProperty, kCaCertNSS);
279 SetArg(flimflam::kL2tpIpsecPskProperty, kPSK);
280
281 FilePath empty_cert;
282 EXPECT_CALL(nss_, GetDERCertfile(kCaCertNSS, _)).WillOnce(Return(empty_cert));
283
284 const FilePath temp_dir(temp_dir_.path());
285 EXPECT_CALL(manager_, run_path()).WillOnce(ReturnRef(temp_dir));
286
287 Error error;
288 vector<string> options;
Darin Petkov209e6292012-04-20 11:33:32 +0200289 EXPECT_TRUE(driver_->InitOptions(&options, &error));
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200290 EXPECT_TRUE(error.IsSuccess());
291
292 ExpectInFlags(options, "--remote_host", kHost);
293 ASSERT_FALSE(driver_->psk_file_.empty());
294 ExpectInFlags(options, "--psk_file", driver_->psk_file_.value());
295}
296
297TEST_F(L2TPIPSecDriverTest, InitPSKOptions) {
298 Error error;
299 vector<string> options;
300 static const char kPSK[] = "foobar";
301 const FilePath bad_dir("/non/existent/directory");
302 const FilePath temp_dir(temp_dir_.path());
303 EXPECT_CALL(manager_, run_path())
304 .WillOnce(ReturnRef(bad_dir))
305 .WillOnce(ReturnRef(temp_dir));
306
307 EXPECT_TRUE(driver_->InitPSKOptions(&options, &error));
308 EXPECT_TRUE(options.empty());
309 EXPECT_TRUE(error.IsSuccess());
310
311 SetArg(flimflam::kL2tpIpsecPskProperty, kPSK);
312
313 EXPECT_FALSE(driver_->InitPSKOptions(&options, &error));
314 EXPECT_TRUE(options.empty());
315 EXPECT_EQ(Error::kInternalError, error.type());
316 error.Reset();
317
318 EXPECT_TRUE(driver_->InitPSKOptions(&options, &error));
319 ASSERT_FALSE(driver_->psk_file_.empty());
320 ExpectInFlags(options, "--psk_file", driver_->psk_file_.value());
321 EXPECT_TRUE(error.IsSuccess());
322 string contents;
323 EXPECT_TRUE(
324 file_util::ReadFileToString(driver_->psk_file_, &contents));
325 EXPECT_EQ(kPSK, contents);
326 struct stat buf;
327 ASSERT_EQ(0, stat(driver_->psk_file_.value().c_str(), &buf));
328 EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR, buf.st_mode);
329}
330
331TEST_F(L2TPIPSecDriverTest, InitNSSOptions) {
332 static const char kHost[] = "192.168.2.254";
333 static const char kCaCertNSS[] = "{1234}";
334 static const char kNSSCertfile[] = "/tmp/nss-cert";
335 FilePath empty_cert;
336 FilePath nss_cert(kNSSCertfile);
337 SetArg(flimflam::kProviderHostProperty, kHost);
338 SetArg(flimflam::kL2tpIpsecCaCertNssProperty, kCaCertNSS);
339 EXPECT_CALL(nss_,
340 GetDERCertfile(kCaCertNSS,
341 ElementsAreArray(kHost, arraysize(kHost) - 1)))
342 .WillOnce(Return(empty_cert))
343 .WillOnce(Return(nss_cert));
344
345 vector<string> options;
346 driver_->InitNSSOptions(&options);
347 EXPECT_TRUE(options.empty());
348 driver_->InitNSSOptions(&options);
349 ExpectInFlags(options, "--server_ca_file", kNSSCertfile);
350}
351
Paul Stewart5baebb72013-03-14 11:43:29 -0700352TEST_F(L2TPIPSecDriverTest, InitPEMOptions) {
353 static const char kCaCertPEM[] = "Insert PEM encoded data here";
354 static const char kPEMCertfile[] = "/tmp/der-file-from-pem-cert";
355 FilePath empty_cert;
356 FilePath pem_cert(kPEMCertfile);
357 SetArg(kL2tpIpsecCaCertPemProperty, kCaCertPEM);
358 EXPECT_CALL(*certificate_file_, CreateDERFromString(kCaCertPEM))
359 .WillOnce(Return(empty_cert))
360 .WillOnce(Return(pem_cert));
361
362 vector<string> options;
363 driver_->InitPEMOptions(&options);
364 EXPECT_TRUE(options.empty());
365 driver_->InitPEMOptions(&options);
366 ExpectInFlags(options, "--server_ca_file", kPEMCertfile);
367}
368
Darin Petkovf7ef50a2012-04-16 20:54:31 +0200369TEST_F(L2TPIPSecDriverTest, AppendValueOption) {
370 static const char kOption[] = "--l2tpipsec-option";
371 static const char kProperty[] = "L2TPIPSec.SomeProperty";
372 static const char kValue[] = "some-property-value";
373 static const char kOption2[] = "--l2tpipsec-option2";
374 static const char kProperty2[] = "L2TPIPSec.SomeProperty2";
375 static const char kValue2[] = "some-property-value2";
376
377 vector<string> options;
378 EXPECT_FALSE(
379 driver_->AppendValueOption(
380 "L2TPIPSec.UnknownProperty", kOption, &options));
381 EXPECT_TRUE(options.empty());
382
383 SetArg(kProperty, "");
384 EXPECT_FALSE(driver_->AppendValueOption(kProperty, kOption, &options));
385 EXPECT_TRUE(options.empty());
386
387 SetArg(kProperty, kValue);
388 SetArg(kProperty2, kValue2);
389 EXPECT_TRUE(driver_->AppendValueOption(kProperty, kOption, &options));
390 EXPECT_TRUE(driver_->AppendValueOption(kProperty2, kOption2, &options));
391 EXPECT_EQ(4, options.size());
392 EXPECT_EQ(kOption, options[0]);
393 EXPECT_EQ(kValue, options[1]);
394 EXPECT_EQ(kOption2, options[2]);
395 EXPECT_EQ(kValue2, options[3]);
396}
397
398TEST_F(L2TPIPSecDriverTest, AppendFlag) {
399 static const char kTrueOption[] = "--l2tpipsec-option";
400 static const char kFalseOption[] = "--nol2tpipsec-option";
401 static const char kProperty[] = "L2TPIPSec.SomeProperty";
402 static const char kTrueOption2[] = "--l2tpipsec-option2";
403 static const char kFalseOption2[] = "--nol2tpipsec-option2";
404 static const char kProperty2[] = "L2TPIPSec.SomeProperty2";
405
406 vector<string> options;
407 EXPECT_FALSE(driver_->AppendFlag("L2TPIPSec.UnknownProperty",
408 kTrueOption, kFalseOption, &options));
409 EXPECT_TRUE(options.empty());
410
411 SetArg(kProperty, "");
412 EXPECT_FALSE(
413 driver_->AppendFlag(kProperty, kTrueOption, kFalseOption, &options));
414 EXPECT_TRUE(options.empty());
415
416 SetArg(kProperty, "true");
417 SetArg(kProperty2, "false");
418 EXPECT_TRUE(
419 driver_->AppendFlag(kProperty, kTrueOption, kFalseOption, &options));
420 EXPECT_TRUE(
421 driver_->AppendFlag(kProperty2, kTrueOption2, kFalseOption2, &options));
422 EXPECT_EQ(2, options.size());
423 EXPECT_EQ(kTrueOption, options[0]);
424 EXPECT_EQ(kFalseOption2, options[1]);
425}
426
Darin Petkov209e6292012-04-20 11:33:32 +0200427TEST_F(L2TPIPSecDriverTest, GetLogin) {
428 static const char kUser[] = "joesmith";
429 static const char kPassword[] = "random-password";
430 string user, password;
431 SetArg(flimflam::kL2tpIpsecUserProperty, kUser);
432 driver_->GetLogin(&user, &password);
433 EXPECT_TRUE(user.empty());
434 EXPECT_TRUE(password.empty());
435 SetArg(flimflam::kL2tpIpsecUserProperty, "");
436 SetArg(flimflam::kL2tpIpsecPasswordProperty, kPassword);
437 driver_->GetLogin(&user, &password);
438 EXPECT_TRUE(user.empty());
439 EXPECT_TRUE(password.empty());
440 SetArg(flimflam::kL2tpIpsecUserProperty, kUser);
441 driver_->GetLogin(&user, &password);
442 EXPECT_EQ(kUser, user);
443 EXPECT_EQ(kPassword, password);
444}
445
446TEST_F(L2TPIPSecDriverTest, OnL2TPIPSecVPNDied) {
447 const int kPID = 99999;
448 driver_->child_watch_tag_ = 333;
449 driver_->pid_ = kPID;
Darin Petkov85d53172013-03-13 16:43:28 +0100450 driver_->service_ = service_;
451 EXPECT_CALL(*service_, SetFailure(Service::kFailureDNSLookup));
Darin Petkov5a850472012-06-06 15:44:24 +0200452 EXPECT_CALL(process_killer_, Kill(_, _)).Times(0);
Darin Petkov85d53172013-03-13 16:43:28 +0100453 L2TPIPSecDriver::OnL2TPIPSecVPNDied(
454 kPID, vpn_manager::kServiceErrorResolveHostnameFailed << 8, driver_);
Darin Petkov209e6292012-04-20 11:33:32 +0200455 EXPECT_EQ(0, driver_->child_watch_tag_);
456 EXPECT_EQ(0, driver_->pid_);
Darin Petkov85d53172013-03-13 16:43:28 +0100457 EXPECT_FALSE(driver_->service_);
Darin Petkov209e6292012-04-20 11:33:32 +0200458}
459
460namespace {
461MATCHER(CheckEnv, "") {
Darin Petkov95f317f2012-10-22 13:37:43 +0200462 if (!arg || !arg[0] || !arg[1] || arg[2]) {
Darin Petkov209e6292012-04-20 11:33:32 +0200463 return false;
464 }
Darin Petkov95f317f2012-10-22 13:37:43 +0200465 return StartsWithASCII(arg[0], "SHILL_TASK_", true);
Darin Petkov209e6292012-04-20 11:33:32 +0200466}
467} // namespace
468
469TEST_F(L2TPIPSecDriverTest, SpawnL2TPIPSecVPN) {
470 Error error;
471 EXPECT_FALSE(driver_->SpawnL2TPIPSecVPN(&error));
472 EXPECT_TRUE(error.IsFailure());
473
474 static const char kHost[] = "192.168.2.254";
475 SetArg(flimflam::kProviderHostProperty, kHost);
476 driver_->rpc_task_.reset(new RPCTask(&control_, this));
477
478 const int kPID = 234678;
Darin Petkov68710d72013-02-13 14:22:56 +0100479 EXPECT_CALL(glib_, SpawnAsync(_, _, CheckEnv(), _, _, _, _, _))
Darin Petkov209e6292012-04-20 11:33:32 +0200480 .WillOnce(Return(false))
Darin Petkov68710d72013-02-13 14:22:56 +0100481 .WillOnce(DoAll(SetArgumentPointee<6>(kPID), Return(true)));
Darin Petkov209e6292012-04-20 11:33:32 +0200482 const int kTag = 6;
483 EXPECT_CALL(glib_, ChildWatchAdd(kPID, &driver_->OnL2TPIPSecVPNDied, driver_))
484 .WillOnce(Return(kTag));
485 error.Reset();
486 EXPECT_FALSE(driver_->SpawnL2TPIPSecVPN(&error));
487 EXPECT_EQ(Error::kInternalError, error.type());
488 error.Reset();
489 EXPECT_TRUE(driver_->SpawnL2TPIPSecVPN(&error));
490 EXPECT_TRUE(error.IsSuccess());
491 EXPECT_EQ(kPID, driver_->pid_);
492 EXPECT_EQ(kTag, driver_->child_watch_tag_);
493}
494
495TEST_F(L2TPIPSecDriverTest, Connect) {
496 EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
497 static const char kHost[] = "192.168.2.254";
498 SetArg(flimflam::kProviderHostProperty, kHost);
Darin Petkov68710d72013-02-13 14:22:56 +0100499 EXPECT_CALL(glib_, SpawnAsync(_, _, _, _, _, _, _, _)).WillOnce(Return(true));
Darin Petkov209e6292012-04-20 11:33:32 +0200500 EXPECT_CALL(glib_, ChildWatchAdd(_, _, _)).WillOnce(Return(1));
501 Error error;
502 driver_->Connect(service_, &error);
503 EXPECT_TRUE(error.IsSuccess());
Darin Petkov602303f2012-06-06 12:15:59 +0200504 EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
Darin Petkov209e6292012-04-20 11:33:32 +0200505}
506
Darin Petkova0e645e2012-04-25 11:38:59 +0200507TEST_F(L2TPIPSecDriverTest, Disconnect) {
508 driver_->device_ = device_;
509 driver_->service_ = service_;
510 EXPECT_CALL(*device_, OnDisconnected());
511 EXPECT_CALL(*device_, SetEnabled(false));
512 EXPECT_CALL(*service_, SetState(Service::kStateIdle));
513 driver_->Disconnect();
514 EXPECT_FALSE(driver_->device_);
515 EXPECT_FALSE(driver_->service_);
516}
517
Darin Petkov5eb05422012-05-11 15:45:25 +0200518TEST_F(L2TPIPSecDriverTest, OnConnectionDisconnected) {
519 driver_->service_ = service_;
Darin Petkova42afe32013-02-05 16:53:52 +0100520 EXPECT_CALL(*service_, SetState(Service::kStateIdle));
Darin Petkov5eb05422012-05-11 15:45:25 +0200521 driver_->OnConnectionDisconnected();
522 EXPECT_FALSE(driver_->service_);
523}
524
Darin Petkova42afe32013-02-05 16:53:52 +0100525TEST_F(L2TPIPSecDriverTest, OnConnectTimeout) {
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100526 StartConnectTimeout(0);
Darin Petkova42afe32013-02-05 16:53:52 +0100527 SetService(service_);
Darin Petkov85d53172013-03-13 16:43:28 +0100528 EXPECT_CALL(*service_, SetFailure(Service::kFailureConnect));
Darin Petkova42afe32013-02-05 16:53:52 +0100529 OnConnectTimeout();
530 EXPECT_FALSE(GetService());
531 EXPECT_FALSE(IsConnectTimeoutStarted());
532}
533
Darin Petkovd4325392012-04-23 15:48:22 +0200534TEST_F(L2TPIPSecDriverTest, InitPropertyStore) {
535 // Sanity test property store initialization.
536 PropertyStore store;
537 driver_->InitPropertyStore(&store);
538 const string kUser = "joe";
539 Error error;
540 EXPECT_TRUE(
541 store.SetStringProperty(flimflam::kL2tpIpsecUserProperty, kUser, &error));
542 EXPECT_TRUE(error.IsSuccess());
Darin Petkovb536a742012-04-26 11:31:28 +0200543 EXPECT_EQ(kUser,
544 GetArgs()->LookupString(flimflam::kL2tpIpsecUserProperty, ""));
545}
546
547TEST_F(L2TPIPSecDriverTest, GetProvider) {
548 PropertyStore store;
549 driver_->InitPropertyStore(&store);
550 {
Darin Petkovb536a742012-04-26 11:31:28 +0200551 KeyValueStore props;
Paul Stewarte6e8e492013-01-17 11:00:50 -0800552 Error error;
Darin Petkov4682aa82012-05-31 16:24:11 +0200553 EXPECT_TRUE(
Paul Stewarte6e8e492013-01-17 11:00:50 -0800554 store.GetKeyValueStoreProperty(
555 flimflam::kProviderProperty, &props, &error));
Darin Petkovb536a742012-04-26 11:31:28 +0200556 EXPECT_TRUE(props.LookupBool(flimflam::kPassphraseRequiredProperty, false));
557 EXPECT_TRUE(
558 props.LookupBool(flimflam::kL2tpIpsecPskRequiredProperty, false));
559 }
560 {
Darin Petkovb536a742012-04-26 11:31:28 +0200561 KeyValueStore props;
562 SetArg(flimflam::kL2tpIpsecPasswordProperty, "random-password");
563 SetArg(flimflam::kL2tpIpsecPskProperty, "random-psk");
Paul Stewarte6e8e492013-01-17 11:00:50 -0800564 Error error;
Darin Petkov4682aa82012-05-31 16:24:11 +0200565 EXPECT_TRUE(
Paul Stewarte6e8e492013-01-17 11:00:50 -0800566 store.GetKeyValueStoreProperty(
567 flimflam::kProviderProperty, &props, &error));
Darin Petkovb536a742012-04-26 11:31:28 +0200568 EXPECT_FALSE(props.LookupBool(flimflam::kPassphraseRequiredProperty, true));
569 EXPECT_FALSE(
570 props.LookupBool(flimflam::kL2tpIpsecPskRequiredProperty, true));
Darin Petkov02236552012-06-11 13:15:19 +0200571 EXPECT_FALSE(props.ContainsString(flimflam::kL2tpIpsecPasswordProperty));
Darin Petkovb536a742012-04-26 11:31:28 +0200572 }
Darin Petkovd4325392012-04-23 15:48:22 +0200573}
574
Darin Petkov0e9735d2012-04-24 12:33:45 +0200575TEST_F(L2TPIPSecDriverTest, ParseIPConfiguration) {
576 map<string, string> config;
Darin Petkov95f317f2012-10-22 13:37:43 +0200577 config[kL2TPIPSecInternalIP4Address] = "4.5.6.7";
578 config[kL2TPIPSecExternalIP4Address] = "33.44.55.66";
579 config[kL2TPIPSecGatewayAddress] = "192.168.1.1";
580 config[kL2TPIPSecDNS1] = "1.1.1.1";
581 config[kL2TPIPSecDNS2] = "2.2.2.2";
582 config[kL2TPIPSecInterfaceName] = "ppp0";
583 config[kL2TPIPSecLNSAddress] = "99.88.77.66";
Darin Petkov0e9735d2012-04-24 12:33:45 +0200584 config["foo"] = "bar";
585 IPConfig::Properties props;
586 string interface_name;
587 L2TPIPSecDriver::ParseIPConfiguration(config, &props, &interface_name);
588 EXPECT_EQ(IPAddress::kFamilyIPv4, props.address_family);
589 EXPECT_EQ("4.5.6.7", props.address);
590 EXPECT_EQ("33.44.55.66", props.peer_address);
591 EXPECT_EQ("192.168.1.1", props.gateway);
592 EXPECT_EQ("99.88.77.66", props.trusted_ip);
593 ASSERT_EQ(2, props.dns_servers.size());
594 EXPECT_EQ("1.1.1.1", props.dns_servers[0]);
595 EXPECT_EQ("2.2.2.2", props.dns_servers[1]);
596 EXPECT_EQ("ppp0", interface_name);
Ben Chana0163122012-09-25 15:10:52 -0700597 EXPECT_TRUE(props.blackhole_ipv6);
Darin Petkov0e9735d2012-04-24 12:33:45 +0200598}
599
600namespace {
601MATCHER_P(IsIPAddress, address, "") {
602 IPAddress ip_address(IPAddress::kFamilyIPv4);
603 EXPECT_TRUE(ip_address.SetAddressFromString(address));
604 return ip_address.Equals(arg);
605}
606} // namespace
607
608TEST_F(L2TPIPSecDriverTest, Notify) {
609 map<string, string> config;
Darin Petkov95f317f2012-10-22 13:37:43 +0200610 config[kL2TPIPSecInterfaceName] = kInterfaceName;
Darin Petkovf8046b82012-04-24 16:29:23 +0200611 EXPECT_CALL(device_info_, GetIndex(kInterfaceName))
612 .WillOnce(Return(kInterfaceIndex));
Darin Petkovf8046b82012-04-24 16:29:23 +0200613 EXPECT_CALL(*device_, SetEnabled(true));
614 EXPECT_CALL(*device_, UpdateIPConfig(_));
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100615 SetDevice(device_);
Darin Petkov0e9735d2012-04-24 12:33:45 +0200616 FilePath psk_file = SetupPSKFile();
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100617 StartConnectTimeout(0);
Paul Stewart91a43cb2013-03-02 21:34:15 -0800618
619 EXPECT_CALL(metrics_, SendEnumToUMA(
620 Metrics::kMetricVpnDriver,
621 Metrics::kVpnDriverL2tpIpsec,
622 Metrics::kMetricVpnDriverMax));
623 EXPECT_CALL(metrics_, SendEnumToUMA(
624 Metrics::kMetricVpnRemoteAuthenticationType,
625 Metrics::kVpnRemoteAuthenticationTypeL2tpIpsecPsk,
626 Metrics::kVpnRemoteAuthenticationTypeMax));
627 EXPECT_CALL(metrics_, SendEnumToUMA(
628 Metrics::kMetricVpnUserAuthenticationType,
629 Metrics::kVpnUserAuthenticationTypeL2tpIpsecUsernamePassword,
630 Metrics::kVpnUserAuthenticationTypeMax));
631
632 Error unused_error;
633 PropertyStore store;
634 driver_->InitPropertyStore(&store);
Paul Stewarte8e71da2013-03-20 08:48:33 -0700635 store.SetStringProperty(flimflam::kL2tpIpsecPskProperty, "x", &unused_error);
636 store.SetStringProperty(flimflam::kL2tpIpsecPasswordProperty, "y",
Paul Stewart91a43cb2013-03-02 21:34:15 -0800637 &unused_error);
638
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100639 InvokeNotify(kL2TPIPSecReasonConnect, config);
Darin Petkov0e9735d2012-04-24 12:33:45 +0200640 EXPECT_FALSE(file_util::PathExists(psk_file));
Darin Petkov0cd0d1e2013-02-11 12:49:10 +0100641 EXPECT_TRUE(GetPSKFile().empty());
642 EXPECT_FALSE(IsConnectTimeoutStarted());
Darin Petkov0e9735d2012-04-24 12:33:45 +0200643}
644
Darin Petkov69990222012-11-14 09:25:25 +0100645TEST_F(L2TPIPSecDriverTest, NotifyDisconnected) {
Darin Petkova0e645e2012-04-25 11:38:59 +0200646 map<string, string> dict;
647 driver_->device_ = device_;
Darin Petkov69990222012-11-14 09:25:25 +0100648 driver_->rpc_task_.reset(new TestRPCTask(&control_, this));
649 EXPECT_FALSE(test_rpc_task_destroyed_);
Darin Petkova0e645e2012-04-25 11:38:59 +0200650 EXPECT_CALL(*device_, OnDisconnected());
Darin Petkov69990222012-11-14 09:25:25 +0100651 EXPECT_CALL(*device_, SetEnabled(false));
Darin Petkov95f317f2012-10-22 13:37:43 +0200652 driver_->Notify(kL2TPIPSecReasonDisconnect, dict);
Darin Petkov69990222012-11-14 09:25:25 +0100653 EXPECT_FALSE(driver_->device_);
654 EXPECT_FALSE(test_rpc_task_destroyed_);
655 EXPECT_FALSE(driver_->rpc_task_.get());
656 dispatcher_.PostTask(MessageLoop::QuitClosure());
657 dispatcher_.DispatchForever();
658 EXPECT_TRUE(test_rpc_task_destroyed_);
Darin Petkova0e645e2012-04-25 11:38:59 +0200659}
660
661TEST_F(L2TPIPSecDriverTest, VerifyPaths) {
662 // Ensure that the various path constants that the L2TP/IPSec driver uses
663 // actually exists in the build image. Due to build dependencies, they should
664 // already exist by the time we run unit tests.
665
666 // The L2TPIPSecDriver path constants are absolute. FilePath::Append asserts
667 // that its argument is not an absolute path, so we need to strip the leading
668 // separators. There's nothing built into FilePath to do so.
669 static const char *kPaths[] = {
670 L2TPIPSecDriver::kL2TPIPSecVPNPath,
671 L2TPIPSecDriver::kPPPDPlugin,
672 };
673 for (size_t i = 0; i < arraysize(kPaths); i++) {
674 string path(kPaths[i]);
675 TrimString(path, FilePath::kSeparators, &path);
676 EXPECT_TRUE(file_util::PathExists(FilePath(SYSROOT).Append(path)))
677 << kPaths[i];
678 }
679}
680
Darin Petkov7476a262012-04-12 16:30:46 +0200681} // namespace shill