l2tp_ipsec_driver_unittest.cc revision 0951ccbfca977a9cf218b2e4308aa26fb4d06ef9
1// 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/vpn/l2tp_ipsec_driver.h"
6
7#include <base/files/file_util.h>
8#include <base/files/scoped_temp_dir.h>
9#include <base/memory/weak_ptr.h>
10#include <base/strings/string_util.h>
11#include <base/strings/stringprintf.h>
12#include <gtest/gtest.h>
13#include <vpn-manager/service_error.h>
14
15#include "shill/event_dispatcher.h"
16#include "shill/mock_adaptors.h"
17#include "shill/mock_certificate_file.h"
18#include "shill/mock_device_info.h"
19#include "shill/mock_external_task.h"
20#include "shill/mock_glib.h"
21#include "shill/mock_manager.h"
22#include "shill/mock_metrics.h"
23#include "shill/mock_ppp_device.h"
24#include "shill/mock_ppp_device_factory.h"
25#include "shill/nice_mock_control.h"
26#include "shill/vpn/mock_vpn_service.h"
27
28using base::FilePath;
29using std::find;
30using std::map;
31using std::string;
32using std::vector;
33using testing::_;
34using testing::ElementsAreArray;
35using testing::Mock;
36using testing::NiceMock;
37using testing::Return;
38using testing::ReturnRef;
39using testing::SetArgumentPointee;
40using testing::StrictMock;
41
42namespace shill {
43
44class L2TPIPSecDriverTest : public testing::Test,
45                            public RPCTaskDelegate {
46 public:
47  L2TPIPSecDriverTest()
48      : device_info_(&control_, &dispatcher_, &metrics_, &manager_),
49        metrics_(&dispatcher_),
50        manager_(&control_, &dispatcher_, &metrics_, &glib_),
51        driver_(new L2TPIPSecDriver(&control_, &dispatcher_, &metrics_,
52                                    &manager_, &device_info_, &glib_)),
53        service_(new MockVPNService(&control_, &dispatcher_, &metrics_,
54                                    &manager_, driver_)),
55        device_(new MockPPPDevice(&control_, &dispatcher_, &metrics_, &manager_,
56                                  kInterfaceName, kInterfaceIndex)),
57        certificate_file_(new MockCertificateFile()),
58        weak_ptr_factory_(this) {
59    driver_->certificate_file_.reset(certificate_file_);  // Passes ownership.
60  }
61
62  virtual ~L2TPIPSecDriverTest() {}
63
64  virtual void SetUp() {
65    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
66  }
67
68  virtual void TearDown() {
69    driver_->device_ = nullptr;
70    driver_->service_ = nullptr;
71    ASSERT_TRUE(temp_dir_.Delete());
72  }
73
74 protected:
75  static const char kInterfaceName[];
76  static const int kInterfaceIndex;
77
78  void SetArg(const string &arg, const string &value) {
79    driver_->args()->SetString(arg, value);
80  }
81
82  void SetArgArray(const string &arg, const vector<string> &value) {
83    driver_->args()->SetStrings(arg, value);
84  }
85
86  KeyValueStore *GetArgs() {
87    return driver_->args();
88  }
89
90  string GetProviderType() {
91    return driver_->GetProviderType();
92  }
93
94  void SetDevice(const PPPDeviceRefPtr &device) {
95    driver_->device_ = device;
96  }
97
98  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
110  void StartConnectTimeout(int timeout_seconds) {
111    driver_->StartConnectTimeout(timeout_seconds);
112  }
113
114  bool IsConnectTimeoutStarted() const {
115    return driver_->IsConnectTimeoutStarted();
116  }
117
118  bool IsPSKFileCleared(const FilePath &psk_file_path) const {
119    return !base::PathExists(psk_file_path) && GetPSKFile().empty();
120  }
121
122  bool IsXauthCredentialsFileCleared(
123      const FilePath &xauth_credentials_file_path) const {
124    return !base::PathExists(xauth_credentials_file_path) &&
125        GetXauthCredentialsFile().empty();
126  }
127
128  // Used to assert that a flag appears in the options.
129  void ExpectInFlags(const vector<string> &options, const string &flag,
130                     const string &value);
131
132  FilePath SetupPSKFile();
133  FilePath SetupXauthCredentialsFile();
134
135  FilePath GetPSKFile() const { return driver_->psk_file_; }
136  FilePath GetXauthCredentialsFile() const {
137      return driver_->xauth_credentials_file_;
138  }
139
140  void InvokeNotify(const string &reason, const map<string, string> &dict) {
141    driver_->Notify(reason, dict);
142  }
143
144  void FakeUpConnect(FilePath *psk_file, FilePath *xauth_credentials_file) {
145    *psk_file = SetupPSKFile();
146    *xauth_credentials_file = SetupXauthCredentialsFile();
147    SetService(service_);
148    StartConnectTimeout(0);
149  }
150
151  void ExpectDeviceConnected(const map<string, string> &ppp_config) {
152    EXPECT_CALL(*device_, SetEnabled(true));
153    EXPECT_CALL(*device_, SelectService(static_cast<ServiceRefPtr>(service_)));
154    EXPECT_CALL(*device_, UpdateIPConfigFromPPP(ppp_config, _));
155  }
156
157  void ExpectMetricsReported() {
158    Error unused_error;
159    PropertyStore store;
160    driver_->InitPropertyStore(&store);
161    store.SetStringProperty(kL2tpIpsecPskProperty, "x", &unused_error);
162    store.SetStringProperty(kL2tpIpsecPasswordProperty, "y", &unused_error);
163    EXPECT_CALL(metrics_, SendEnumToUMA(
164        Metrics::kMetricVpnDriver,
165        Metrics::kVpnDriverL2tpIpsec,
166        Metrics::kMetricVpnDriverMax));
167    EXPECT_CALL(metrics_, SendEnumToUMA(
168        Metrics::kMetricVpnRemoteAuthenticationType,
169        Metrics::kVpnRemoteAuthenticationTypeL2tpIpsecPsk,
170        Metrics::kVpnRemoteAuthenticationTypeMax));
171    EXPECT_CALL(metrics_, SendEnumToUMA(
172        Metrics::kMetricVpnUserAuthenticationType,
173        Metrics::kVpnUserAuthenticationTypeL2tpIpsecUsernamePassword,
174        Metrics::kVpnUserAuthenticationTypeMax));
175  }
176
177  // Inherited from RPCTaskDelegate.
178  virtual void GetLogin(string *user, string *password);
179  virtual void Notify(const string &reason, const map<string, string> &dict);
180
181  base::ScopedTempDir temp_dir_;
182  NiceMockControl control_;
183  NiceMock<MockDeviceInfo> device_info_;
184  EventDispatcher dispatcher_;
185  MockMetrics metrics_;
186  MockGLib glib_;
187  MockManager manager_;
188  L2TPIPSecDriver *driver_;  // Owned by |service_|.
189  scoped_refptr<MockVPNService> service_;
190  scoped_refptr<MockPPPDevice> device_;
191  MockCertificateFile *certificate_file_;  // Owned by |driver_|.
192  base::WeakPtrFactory<L2TPIPSecDriverTest> weak_ptr_factory_;
193};
194
195const char L2TPIPSecDriverTest::kInterfaceName[] = "ppp0";
196const int L2TPIPSecDriverTest::kInterfaceIndex = 123;
197
198void L2TPIPSecDriverTest::GetLogin(string */*user*/, string */*password*/) {}
199
200void L2TPIPSecDriverTest::Notify(
201    const string &/*reason*/, const map<string, string> &/*dict*/) {}
202
203void L2TPIPSecDriverTest::ExpectInFlags(
204    const vector<string> &options, const string &flag, const string &value) {
205  string flagValue = base::StringPrintf("%s=%s", flag.c_str(), value.c_str());
206  vector<string>::const_iterator it =
207      find(options.begin(), options.end(), flagValue);
208
209  EXPECT_TRUE(it != options.end());
210}
211
212FilePath L2TPIPSecDriverTest::SetupPSKFile() {
213  FilePath psk_file;
214  EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(), &psk_file));
215  EXPECT_FALSE(psk_file.empty());
216  EXPECT_TRUE(base::PathExists(psk_file));
217  driver_->psk_file_ = psk_file;
218  return psk_file;
219}
220
221FilePath L2TPIPSecDriverTest::SetupXauthCredentialsFile() {
222  FilePath xauth_credentials_file;
223  EXPECT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
224                                             &xauth_credentials_file));
225  EXPECT_FALSE(xauth_credentials_file.empty());
226  EXPECT_TRUE(base::PathExists(xauth_credentials_file));
227  driver_->xauth_credentials_file_ = xauth_credentials_file;
228  return xauth_credentials_file;
229}
230
231TEST_F(L2TPIPSecDriverTest, GetProviderType) {
232  EXPECT_EQ(kProviderL2tpIpsec, GetProviderType());
233}
234
235TEST_F(L2TPIPSecDriverTest, Cleanup) {
236  driver_->IdleService();  // Ensure no crash.
237
238  FilePath psk_file;
239  FilePath xauth_credentials_file;
240  FakeUpConnect(&psk_file, &xauth_credentials_file);
241  driver_->device_ = device_;
242  driver_->external_task_.reset(
243      new MockExternalTask(&control_,
244                           &glib_,
245                           weak_ptr_factory_.GetWeakPtr(),
246                           base::Callback<void(pid_t, int)>()));
247  EXPECT_CALL(*device_, DropConnection());
248  EXPECT_CALL(*device_, SetEnabled(false));
249  EXPECT_CALL(*service_, SetFailure(Service::kFailureBadPassphrase));
250  driver_->FailService(Service::kFailureBadPassphrase);  // Trigger Cleanup.
251  EXPECT_TRUE(IsPSKFileCleared(psk_file));
252  EXPECT_TRUE(IsXauthCredentialsFileCleared(xauth_credentials_file));
253  EXPECT_FALSE(driver_->device_);
254  EXPECT_FALSE(driver_->service_);
255  EXPECT_FALSE(driver_->IsConnectTimeoutStarted());
256  EXPECT_FALSE(driver_->external_task_);
257
258  driver_->service_ = service_;
259  EXPECT_CALL(*service_, SetState(Service::kStateIdle));
260  driver_->IdleService();
261  EXPECT_FALSE(driver_->service_);
262}
263
264TEST_F(L2TPIPSecDriverTest, DeleteTemporaryFiles) {
265  FilePath psk_file = SetupPSKFile();
266  FilePath xauth_credentials_file = SetupXauthCredentialsFile();
267  driver_->DeleteTemporaryFiles();
268  EXPECT_TRUE(IsPSKFileCleared(psk_file));
269  EXPECT_TRUE(IsXauthCredentialsFileCleared(xauth_credentials_file));
270}
271
272TEST_F(L2TPIPSecDriverTest, InitOptionsNoHost) {
273  Error error;
274  vector<string> options;
275  EXPECT_FALSE(driver_->InitOptions(&options, &error));
276  EXPECT_EQ(Error::kInvalidArguments, error.type());
277  EXPECT_TRUE(options.empty());
278}
279
280TEST_F(L2TPIPSecDriverTest, InitOptions) {
281  static const char kHost[] = "192.168.2.254";
282  static const char kPSK[] = "foobar";
283  static const char kXauthUser[] = "silly";
284  static const char kXauthPassword[] = "rabbit";
285  const vector<string> kCaCertPEM{ "Insert PEM encoded data here" };
286  static const char kPEMCertfile[] = "/tmp/der-file-from-pem-cert";
287  FilePath pem_cert(kPEMCertfile);
288
289  SetArg(kProviderHostProperty, kHost);
290  SetArg(kL2tpIpsecPskProperty, kPSK);
291  SetArg(kL2tpIpsecXauthUserProperty, kXauthUser);
292  SetArg(kL2tpIpsecXauthPasswordProperty, kXauthPassword);
293  SetArgArray(kL2tpIpsecCaCertPemProperty, kCaCertPEM);
294
295  EXPECT_CALL(*certificate_file_, CreatePEMFromStrings(kCaCertPEM))
296      .WillOnce(Return(pem_cert));
297  const FilePath temp_dir(temp_dir_.path());
298  // Once each for PSK and Xauth options.
299  EXPECT_CALL(manager_, run_path())
300      .WillOnce(ReturnRef(temp_dir))
301      .WillOnce(ReturnRef(temp_dir));
302
303  Error error;
304  vector<string> options;
305  EXPECT_TRUE(driver_->InitOptions(&options, &error));
306  EXPECT_TRUE(error.IsSuccess());
307
308  ExpectInFlags(options, "--remote_host", kHost);
309  ASSERT_FALSE(driver_->psk_file_.empty());
310  ExpectInFlags(options, "--psk_file", driver_->psk_file_.value());
311  ASSERT_FALSE(driver_->xauth_credentials_file_.empty());
312  ExpectInFlags(options, "--xauth_credentials_file",
313                driver_->xauth_credentials_file_.value());
314  ExpectInFlags(options, "--server_ca_file", kPEMCertfile);
315}
316
317TEST_F(L2TPIPSecDriverTest, InitPSKOptions) {
318  Error error;
319  vector<string> options;
320  static const char kPSK[] = "foobar";
321  const FilePath bad_dir("/non/existent/directory");
322  const FilePath temp_dir(temp_dir_.path());
323  EXPECT_CALL(manager_, run_path())
324      .WillOnce(ReturnRef(bad_dir))
325      .WillOnce(ReturnRef(temp_dir));
326
327  EXPECT_TRUE(driver_->InitPSKOptions(&options, &error));
328  EXPECT_TRUE(options.empty());
329  EXPECT_TRUE(error.IsSuccess());
330
331  SetArg(kL2tpIpsecPskProperty, kPSK);
332
333  EXPECT_FALSE(driver_->InitPSKOptions(&options, &error));
334  EXPECT_TRUE(options.empty());
335  EXPECT_EQ(Error::kInternalError, error.type());
336  error.Reset();
337
338  EXPECT_TRUE(driver_->InitPSKOptions(&options, &error));
339  ASSERT_FALSE(driver_->psk_file_.empty());
340  ExpectInFlags(options, "--psk_file", driver_->psk_file_.value());
341  EXPECT_TRUE(error.IsSuccess());
342  string contents;
343  EXPECT_TRUE(base::ReadFileToString(driver_->psk_file_, &contents));
344  EXPECT_EQ(kPSK, contents);
345  struct stat buf;
346  ASSERT_EQ(0, stat(driver_->psk_file_.value().c_str(), &buf));
347  EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR, buf.st_mode);
348}
349
350TEST_F(L2TPIPSecDriverTest, InitPEMOptions) {
351  const vector<string> kCaCertPEM{ "Insert PEM encoded data here" };
352  static const char kPEMCertfile[] = "/tmp/der-file-from-pem-cert";
353  FilePath empty_cert;
354  FilePath pem_cert(kPEMCertfile);
355  SetArgArray(kL2tpIpsecCaCertPemProperty, kCaCertPEM);
356  EXPECT_CALL(*certificate_file_, CreatePEMFromStrings(kCaCertPEM))
357      .WillOnce(Return(empty_cert))
358      .WillOnce(Return(pem_cert));
359
360  vector<string> options;
361  driver_->InitPEMOptions(&options);
362  EXPECT_TRUE(options.empty());
363  driver_->InitPEMOptions(&options);
364  ExpectInFlags(options, "--server_ca_file", kPEMCertfile);
365}
366
367TEST_F(L2TPIPSecDriverTest, InitXauthOptions) {
368  vector<string> options;
369  EXPECT_CALL(manager_, run_path()).Times(0);
370  {
371    Error error;
372    EXPECT_TRUE(driver_->InitXauthOptions(&options, &error));
373    EXPECT_TRUE(error.IsSuccess());
374  }
375  EXPECT_TRUE(options.empty());
376
377  static const char kUser[] = "foobar";
378  SetArg(kL2tpIpsecXauthUserProperty, kUser);
379  {
380    Error error;
381    EXPECT_FALSE(driver_->InitXauthOptions(&options, &error));
382    EXPECT_EQ(Error::kInvalidArguments, error.type());
383  }
384  EXPECT_TRUE(options.empty());
385
386  static const char kPassword[] = "foobar";
387  SetArg(kL2tpIpsecXauthUserProperty, "");
388  SetArg(kL2tpIpsecXauthPasswordProperty, kPassword);
389  {
390    Error error;
391    EXPECT_FALSE(driver_->InitXauthOptions(&options, &error));
392    EXPECT_EQ(Error::kInvalidArguments, error.type());
393  }
394  EXPECT_TRUE(options.empty());
395  Mock::VerifyAndClearExpectations(&manager_);
396
397  SetArg(kL2tpIpsecXauthUserProperty, kUser);
398  const FilePath bad_dir("/non/existent/directory");
399  const FilePath temp_dir(temp_dir_.path());
400  EXPECT_CALL(manager_, run_path())
401      .WillOnce(ReturnRef(bad_dir))
402      .WillOnce(ReturnRef(temp_dir));
403
404  {
405    Error error;
406    EXPECT_FALSE(driver_->InitXauthOptions(&options, &error));
407    EXPECT_EQ(Error::kInternalError, error.type());
408  }
409  EXPECT_TRUE(options.empty());
410
411  {
412    Error error;
413    EXPECT_TRUE(driver_->InitXauthOptions(&options, &error));
414    EXPECT_TRUE(error.IsSuccess());
415  }
416  ASSERT_FALSE(driver_->xauth_credentials_file_.empty());
417  ExpectInFlags(options, "--xauth_credentials_file",
418                driver_->xauth_credentials_file_.value());
419  string contents;
420  EXPECT_TRUE(
421      base::ReadFileToString(driver_->xauth_credentials_file_, &contents));
422  string expected_contents(string(kUser) + "\n" + kPassword + "\n");
423  EXPECT_EQ(expected_contents, contents);
424  struct stat buf;
425  ASSERT_EQ(0, stat(driver_->xauth_credentials_file_.value().c_str(), &buf));
426  EXPECT_EQ(S_IFREG | S_IRUSR | S_IWUSR, buf.st_mode);
427}
428
429TEST_F(L2TPIPSecDriverTest, AppendValueOption) {
430  static const char kOption[] = "--l2tpipsec-option";
431  static const char kProperty[] = "L2TPIPSec.SomeProperty";
432  static const char kValue[] = "some-property-value";
433  static const char kOption2[] = "--l2tpipsec-option2";
434  static const char kProperty2[] = "L2TPIPSec.SomeProperty2";
435  static const char kValue2[] = "some-property-value2";
436
437  vector<string> options;
438  EXPECT_FALSE(
439      driver_->AppendValueOption(
440          "L2TPIPSec.UnknownProperty", kOption, &options));
441  EXPECT_TRUE(options.empty());
442
443  SetArg(kProperty, "");
444  EXPECT_FALSE(driver_->AppendValueOption(kProperty, kOption, &options));
445  EXPECT_TRUE(options.empty());
446
447  SetArg(kProperty, kValue);
448  SetArg(kProperty2, kValue2);
449  EXPECT_TRUE(driver_->AppendValueOption(kProperty, kOption, &options));
450  EXPECT_TRUE(driver_->AppendValueOption(kProperty2, kOption2, &options));
451  EXPECT_EQ(2, options.size());
452  EXPECT_EQ(base::StringPrintf("%s=%s", kOption, kValue), options[0]);
453  EXPECT_EQ(base::StringPrintf("%s=%s", kOption2, kValue2), options[1]);
454}
455
456TEST_F(L2TPIPSecDriverTest, AppendFlag) {
457  static const char kTrueOption[] = "--l2tpipsec-option";
458  static const char kFalseOption[] = "--nol2tpipsec-option";
459  static const char kProperty[] = "L2TPIPSec.SomeProperty";
460  static const char kTrueOption2[] = "--l2tpipsec-option2";
461  static const char kFalseOption2[] = "--nol2tpipsec-option2";
462  static const char kProperty2[] = "L2TPIPSec.SomeProperty2";
463
464  vector<string> options;
465  EXPECT_FALSE(driver_->AppendFlag("L2TPIPSec.UnknownProperty",
466                                   kTrueOption, kFalseOption, &options));
467  EXPECT_TRUE(options.empty());
468
469  SetArg(kProperty, "");
470  EXPECT_FALSE(
471      driver_->AppendFlag(kProperty, kTrueOption, kFalseOption, &options));
472  EXPECT_TRUE(options.empty());
473
474  SetArg(kProperty, "true");
475  SetArg(kProperty2, "false");
476  EXPECT_TRUE(
477      driver_->AppendFlag(kProperty, kTrueOption, kFalseOption, &options));
478  EXPECT_TRUE(
479      driver_->AppendFlag(kProperty2, kTrueOption2, kFalseOption2, &options));
480  EXPECT_EQ(2, options.size());
481  EXPECT_EQ(kTrueOption, options[0]);
482  EXPECT_EQ(kFalseOption2, options[1]);
483}
484
485TEST_F(L2TPIPSecDriverTest, GetLogin) {
486  static const char kUser[] = "joesmith";
487  static const char kPassword[] = "random-password";
488  string user, password;
489  SetArg(kL2tpIpsecUserProperty, kUser);
490  driver_->GetLogin(&user, &password);
491  EXPECT_TRUE(user.empty());
492  EXPECT_TRUE(password.empty());
493  SetArg(kL2tpIpsecUserProperty, "");
494  SetArg(kL2tpIpsecPasswordProperty, kPassword);
495  driver_->GetLogin(&user, &password);
496  EXPECT_TRUE(user.empty());
497  EXPECT_TRUE(password.empty());
498  SetArg(kL2tpIpsecUserProperty, kUser);
499  driver_->GetLogin(&user, &password);
500  EXPECT_EQ(kUser, user);
501  EXPECT_EQ(kPassword, password);
502}
503
504TEST_F(L2TPIPSecDriverTest, OnL2TPIPSecVPNDied) {
505  const int kPID = 123456;
506  driver_->service_ = service_;
507  EXPECT_CALL(*service_, SetFailure(Service::kFailureDNSLookup));
508  driver_->OnL2TPIPSecVPNDied(
509      kPID, vpn_manager::kServiceErrorResolveHostnameFailed << 8);
510  EXPECT_FALSE(driver_->service_);
511}
512
513TEST_F(L2TPIPSecDriverTest, SpawnL2TPIPSecVPN) {
514  Error error;
515  // Fail without sufficient arguments.
516  EXPECT_FALSE(driver_->SpawnL2TPIPSecVPN(&error));
517  EXPECT_TRUE(error.IsFailure());
518
519  // Provide the required arguments.
520  static const char kHost[] = "192.168.2.254";
521  SetArg(kProviderHostProperty, kHost);
522
523  // TODO(quiche): Instead of setting expectations based on what
524  // ExternalTask will call, mock out ExternalTask. Non-trivial,
525  // though, because ExternalTask is constructed during the
526  // call to driver_->Connect.
527  EXPECT_CALL(glib_, SpawnAsync(_, _, _, _, _, _, _, _)).
528      WillOnce(Return(false)).
529      WillOnce(Return(true));
530  EXPECT_CALL(glib_, ChildWatchAdd(_, _, _));
531
532  EXPECT_FALSE(driver_->SpawnL2TPIPSecVPN(&error));
533  EXPECT_FALSE(driver_->external_task_);
534  EXPECT_TRUE(driver_->SpawnL2TPIPSecVPN(&error));
535  EXPECT_NE(nullptr, driver_->external_task_);
536}
537
538TEST_F(L2TPIPSecDriverTest, Connect) {
539  EXPECT_CALL(*service_, SetState(Service::kStateConfiguring));
540  static const char kHost[] = "192.168.2.254";
541  SetArg(kProviderHostProperty, kHost);
542
543  // TODO(quiche): Instead of setting expectations based on what
544  // ExternalTask will call, mock out ExternalTask. Non-trivial,
545  // though, because ExternalTask is constructed during the
546  // call to driver_->Connect.
547  EXPECT_CALL(glib_, SpawnAsync(_, _, _, _, _, _, _, _)).WillOnce(Return(true));
548  EXPECT_CALL(glib_, ChildWatchAdd(_, _, _)).WillOnce(Return(1));
549
550  Error error;
551  driver_->Connect(service_, &error);
552  EXPECT_TRUE(error.IsSuccess());
553  EXPECT_TRUE(driver_->IsConnectTimeoutStarted());
554}
555
556TEST_F(L2TPIPSecDriverTest, Disconnect) {
557  driver_->device_ = device_;
558  driver_->service_ = service_;
559  EXPECT_CALL(*device_, DropConnection());
560  EXPECT_CALL(*device_, SetEnabled(false));
561  EXPECT_CALL(*service_, SetState(Service::kStateIdle));
562  driver_->Disconnect();
563  EXPECT_FALSE(driver_->device_);
564  EXPECT_FALSE(driver_->service_);
565}
566
567TEST_F(L2TPIPSecDriverTest, OnConnectionDisconnected) {
568  driver_->service_ = service_;
569  EXPECT_CALL(*service_, SetState(Service::kStateIdle));
570  driver_->OnConnectionDisconnected();
571  EXPECT_FALSE(driver_->service_);
572}
573
574TEST_F(L2TPIPSecDriverTest, OnConnectTimeout) {
575  StartConnectTimeout(0);
576  SetService(service_);
577  EXPECT_CALL(*service_, SetFailure(Service::kFailureConnect));
578  OnConnectTimeout();
579  EXPECT_FALSE(GetService());
580  EXPECT_FALSE(IsConnectTimeoutStarted());
581}
582
583TEST_F(L2TPIPSecDriverTest, InitPropertyStore) {
584  // Sanity test property store initialization.
585  PropertyStore store;
586  driver_->InitPropertyStore(&store);
587  const string kUser = "joe";
588  Error error;
589  EXPECT_TRUE(store.SetStringProperty(kL2tpIpsecUserProperty, kUser, &error));
590  EXPECT_TRUE(error.IsSuccess());
591  EXPECT_EQ(kUser, GetArgs()->LookupString(kL2tpIpsecUserProperty, ""));
592}
593
594TEST_F(L2TPIPSecDriverTest, GetProvider) {
595  PropertyStore store;
596  driver_->InitPropertyStore(&store);
597  {
598    KeyValueStore props;
599    Error error;
600    SetArg(kL2tpIpsecClientCertIdProperty, "");
601    EXPECT_TRUE(
602        store.GetKeyValueStoreProperty(kProviderProperty, &props, &error));
603    EXPECT_TRUE(props.LookupBool(kPassphraseRequiredProperty, false));
604    EXPECT_TRUE(props.LookupBool(kL2tpIpsecPskRequiredProperty, false));
605  }
606  {
607    KeyValueStore props;
608    Error error;
609    SetArg(kL2tpIpsecClientCertIdProperty, "some-cert-id");
610    EXPECT_TRUE(
611        store.GetKeyValueStoreProperty(kProviderProperty, &props, &error));
612    EXPECT_TRUE(props.LookupBool(kPassphraseRequiredProperty, false));
613    EXPECT_FALSE(props.LookupBool(kL2tpIpsecPskRequiredProperty, true));
614    SetArg(kL2tpIpsecClientCertIdProperty, "");
615  }
616  {
617    KeyValueStore props;
618    SetArg(kL2tpIpsecPasswordProperty, "random-password");
619    SetArg(kL2tpIpsecPskProperty, "random-psk");
620    Error error;
621    EXPECT_TRUE(
622        store.GetKeyValueStoreProperty(kProviderProperty, &props, &error));
623    EXPECT_FALSE(props.LookupBool(kPassphraseRequiredProperty, true));
624    EXPECT_FALSE(
625        props.LookupBool(kL2tpIpsecPskRequiredProperty, true));
626    EXPECT_FALSE(props.ContainsString(kL2tpIpsecPasswordProperty));
627  }
628}
629
630namespace {
631MATCHER_P(IsIPAddress, address, "") {
632  IPAddress ip_address(IPAddress::kFamilyIPv4);
633  EXPECT_TRUE(ip_address.SetAddressFromString(address));
634  return ip_address.Equals(arg);
635}
636}  // namespace
637
638TEST_F(L2TPIPSecDriverTest, Notify) {
639  map<string, string> config{{kPPPInterfaceName, kInterfaceName}};
640  MockPPPDeviceFactory *mock_ppp_device_factory =
641      MockPPPDeviceFactory::GetInstance();
642  FilePath psk_file;
643  FilePath xauth_credentials_file;
644  FakeUpConnect(&psk_file, &xauth_credentials_file);
645  driver_->ppp_device_factory_ = mock_ppp_device_factory;
646  EXPECT_CALL(device_info_, GetIndex(kInterfaceName))
647      .WillOnce(Return(kInterfaceIndex));
648  EXPECT_CALL(*mock_ppp_device_factory,
649              CreatePPPDevice(_, _, _, _, kInterfaceName, kInterfaceIndex))
650      .WillOnce(Return(device_.get()));
651
652  // Make sure that a notification of an intermediate state doesn't cause
653  // the driver to fail the connection.
654  ASSERT_TRUE(driver_->service_);
655  VPNServiceConstRefPtr service = driver_->service_;
656  InvokeNotify(kPPPReasonAuthenticating, config);
657  InvokeNotify(kPPPReasonAuthenticated, config);
658  EXPECT_TRUE(driver_->service_);
659  EXPECT_FALSE(service->IsFailed());
660
661  ExpectDeviceConnected(config);
662  ExpectMetricsReported();
663  InvokeNotify(kPPPReasonConnect, config);
664  EXPECT_TRUE(IsPSKFileCleared(psk_file));
665  EXPECT_TRUE(IsXauthCredentialsFileCleared(xauth_credentials_file));
666  EXPECT_FALSE(IsConnectTimeoutStarted());
667}
668
669
670TEST_F(L2TPIPSecDriverTest, NotifyWithExistingDevice) {
671  map<string, string> config{{kPPPInterfaceName, kInterfaceName}};
672  MockPPPDeviceFactory *mock_ppp_device_factory =
673      MockPPPDeviceFactory::GetInstance();
674  FilePath psk_file;
675  FilePath xauth_credentials_file;
676  FakeUpConnect(&psk_file, &xauth_credentials_file);
677  driver_->ppp_device_factory_ = mock_ppp_device_factory;
678  SetDevice(device_);
679  EXPECT_CALL(device_info_, GetIndex(kInterfaceName))
680      .WillOnce(Return(kInterfaceIndex));
681  EXPECT_CALL(*mock_ppp_device_factory,
682              CreatePPPDevice(_, _, _, _, _, _)).Times(0);
683  ExpectDeviceConnected(config);
684  ExpectMetricsReported();
685  InvokeNotify(kPPPReasonConnect, config);
686  EXPECT_TRUE(IsPSKFileCleared(psk_file));
687  EXPECT_TRUE(IsXauthCredentialsFileCleared(xauth_credentials_file));
688  EXPECT_FALSE(IsConnectTimeoutStarted());
689}
690
691TEST_F(L2TPIPSecDriverTest, NotifyDisconnected) {
692  map<string, string> dict;
693  base::Callback<void(pid_t, int)> death_callback;
694  MockExternalTask *local_external_task =
695      new MockExternalTask(&control_, &glib_, weak_ptr_factory_.GetWeakPtr(),
696                           death_callback);
697  driver_->device_ = device_;
698  driver_->external_task_.reset(local_external_task);  // passes ownership
699  EXPECT_CALL(*device_, DropConnection());
700  EXPECT_CALL(*device_, SetEnabled(false));
701  EXPECT_CALL(*local_external_task, OnDelete())
702      .Times(0);  // Not until event loop.
703  driver_->Notify(kPPPReasonDisconnect, dict);
704  EXPECT_FALSE(driver_->device_);
705  EXPECT_FALSE(driver_->external_task_.get());
706  Mock::VerifyAndClearExpectations(local_external_task);
707
708  EXPECT_CALL(*local_external_task, OnDelete());
709  dispatcher_.PostTask(base::MessageLoop::QuitClosure());
710  dispatcher_.DispatchForever();
711}
712
713}  // namespace shill
714