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