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