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/vpn_driver.h" 18 19 #include <vector> 20 21 #include <base/stl_util.h> 22 #include <base/strings/string_number_conversions.h> 23 #if defined(__ANDROID__) 24 #include <dbus/service_constants.h> 25 #else 26 #include <chromeos/dbus/service_constants.h> 27 #endif // __ANDROID__ 28 #include <gmock/gmock.h> 29 #include <gtest/gtest.h> 30 31 #include "shill/mock_connection.h" 32 #include "shill/mock_device_info.h" 33 #include "shill/mock_manager.h" 34 #include "shill/mock_metrics.h" 35 #include "shill/mock_service.h" 36 #include "shill/mock_store.h" 37 #include "shill/nice_mock_control.h" 38 #include "shill/property_store.h" 39 #include "shill/test_event_dispatcher.h" 40 41 using std::string; 42 using std::vector; 43 using testing::_; 44 using testing::AnyNumber; 45 using testing::NiceMock; 46 using testing::Return; 47 using testing::SetArgumentPointee; 48 using testing::StrictMock; 49 using testing::Test; 50 51 namespace shill { 52 53 namespace { 54 55 const char kVPNHostProperty[] = "VPN.Host"; 56 const char kOTPProperty[] = "VPN.OTP"; 57 const char kPINProperty[] = "VPN.PIN"; 58 const char kPSKProperty[] = "VPN.PSK"; 59 const char kPasswordProperty[] = "VPN.Password"; 60 const char kPortProperty[] = "VPN.Port"; 61 62 const char kPIN[] = "5555"; 63 const char kPassword[] = "random-password"; 64 const char kPort[] = "1234"; 65 const char kStorageID[] = "vpn_service_id"; 66 67 } // namespace 68 69 class VPNDriverUnderTest : public VPNDriver { 70 public: 71 VPNDriverUnderTest(EventDispatcher* dispatcher, Manager* manager); 72 virtual ~VPNDriverUnderTest() {} 73 74 // Inherited from VPNDriver. 75 MOCK_METHOD2(ClaimInterface, bool(const string& link_name, 76 int interface_index)); 77 MOCK_METHOD2(Connect, void(const VPNServiceRefPtr& service, Error* error)); 78 MOCK_METHOD0(Disconnect, void()); 79 MOCK_METHOD0(OnConnectionDisconnected, void()); 80 MOCK_CONST_METHOD0(GetProviderType, string()); 81 82 private: 83 static const Property kProperties[]; 84 85 DISALLOW_COPY_AND_ASSIGN(VPNDriverUnderTest); 86 }; 87 88 // static 89 const VPNDriverUnderTest::Property VPNDriverUnderTest::kProperties[] = { 90 { kEapCaCertPemProperty, Property::kArray }, 91 { kVPNHostProperty, 0 }, 92 { kL2tpIpsecCaCertPemProperty, Property::kArray }, 93 { kOTPProperty, Property::kEphemeral }, 94 { kPINProperty, Property::kWriteOnly }, 95 { kPSKProperty, Property::kCredential }, 96 { kPasswordProperty, Property::kCredential }, 97 { kPortProperty, 0 }, 98 { kProviderTypeProperty, 0 }, 99 }; 100 101 VPNDriverUnderTest::VPNDriverUnderTest( 102 EventDispatcher* dispatcher, Manager* manager) 103 : VPNDriver(dispatcher, manager, kProperties, arraysize(kProperties)) {} 104 105 class VPNDriverTest : public Test { 106 public: 107 VPNDriverTest() 108 : device_info_(&control_, &dispatcher_, &metrics_, &manager_), 109 metrics_(&dispatcher_), 110 manager_(&control_, &dispatcher_, &metrics_), 111 driver_(&dispatcher_, &manager_) {} 112 113 virtual ~VPNDriverTest() {} 114 115 protected: 116 EventDispatcher* dispatcher() { return driver_.dispatcher_; } 117 void set_dispatcher(EventDispatcher* dispatcher) { 118 driver_.dispatcher_ = dispatcher; 119 } 120 121 const base::CancelableClosure& connect_timeout_callback() { 122 return driver_.connect_timeout_callback_; 123 } 124 125 bool IsConnectTimeoutStarted() { return driver_.IsConnectTimeoutStarted(); } 126 int connect_timeout_seconds() { return driver_.connect_timeout_seconds(); } 127 128 void StartConnectTimeout(int timeout_seconds) { 129 driver_.StartConnectTimeout(timeout_seconds); 130 } 131 132 void StopConnectTimeout() { driver_.StopConnectTimeout(); } 133 134 void SetArg(const string& arg, const string& value) { 135 driver_.args()->SetString(arg, value); 136 } 137 138 void SetArgArray(const string& arg, const vector<string>& value) { 139 driver_.args()->SetStrings(arg, value); 140 } 141 142 KeyValueStore* GetArgs() { return driver_.args(); } 143 144 bool GetProviderPropertyString(const PropertyStore& store, 145 const string& key, 146 string* value); 147 148 bool GetProviderPropertyStrings(const PropertyStore& store, 149 const string& key, 150 vector<string>* value); 151 152 NiceMockControl control_; 153 NiceMock<MockDeviceInfo> device_info_; 154 EventDispatcherForTest dispatcher_; 155 MockMetrics metrics_; 156 MockManager manager_; 157 VPNDriverUnderTest driver_; 158 }; 159 160 bool VPNDriverTest::GetProviderPropertyString(const PropertyStore& store, 161 const string& key, 162 string* value) { 163 KeyValueStore provider_properties; 164 Error error; 165 EXPECT_TRUE(store.GetKeyValueStoreProperty( 166 kProviderProperty, &provider_properties, &error)); 167 if (!provider_properties.ContainsString(key)) { 168 return false; 169 } 170 if (value != nullptr) { 171 *value = provider_properties.GetString(key); 172 } 173 return true; 174 } 175 176 bool VPNDriverTest::GetProviderPropertyStrings(const PropertyStore& store, 177 const string& key, 178 vector<string>* value) { 179 KeyValueStore provider_properties; 180 Error error; 181 EXPECT_TRUE(store.GetKeyValueStoreProperty( 182 kProviderProperty, &provider_properties, &error)); 183 if (!provider_properties.ContainsStrings(key)) { 184 return false; 185 } 186 if (value != nullptr) { 187 *value = provider_properties.GetStrings(key); 188 } 189 return true; 190 } 191 192 TEST_F(VPNDriverTest, Load) { 193 MockStore storage; 194 GetArgs()->SetString(kVPNHostProperty, "1.2.3.4"); 195 GetArgs()->SetString(kPSKProperty, "1234"); 196 GetArgs()->SetStrings(kL2tpIpsecCaCertPemProperty, 197 vector<string>{ "cleared-cert0", "cleared-cert1" }); 198 EXPECT_CALL(storage, GetString(kStorageID, _, _)) 199 .WillRepeatedly(Return(false)); 200 EXPECT_CALL(storage, GetStringList(kStorageID, _, _)) 201 .WillRepeatedly(Return(false)); 202 EXPECT_CALL(storage, GetString(_, kEapCaCertPemProperty, _)).Times(0); 203 EXPECT_CALL(storage, GetString(_, kOTPProperty, _)).Times(0); 204 EXPECT_CALL(storage, GetCryptedString(_, kOTPProperty, _)).Times(0); 205 EXPECT_CALL(storage, GetStringList(_, kOTPProperty, _)).Times(0); 206 vector<string> kCaCerts{ "cert0", "cert1" }; 207 EXPECT_CALL(storage, GetStringList(kStorageID, kEapCaCertPemProperty, _)) 208 .WillOnce(DoAll(SetArgumentPointee<2>(kCaCerts), Return(true))); 209 EXPECT_CALL(storage, GetString(kStorageID, kPortProperty, _)) 210 .WillOnce(DoAll(SetArgumentPointee<2>(string(kPort)), Return(true))); 211 EXPECT_CALL(storage, GetString(kStorageID, kPINProperty, _)) 212 .WillOnce(DoAll(SetArgumentPointee<2>(string(kPIN)), Return(true))); 213 EXPECT_CALL(storage, GetCryptedString(kStorageID, kPSKProperty, _)) 214 .WillOnce(Return(false)); 215 EXPECT_CALL(storage, GetCryptedString(kStorageID, kPasswordProperty, _)) 216 .WillOnce(DoAll(SetArgumentPointee<2>(string(kPassword)), Return(true))); 217 EXPECT_TRUE(driver_.Load(&storage, kStorageID)); 218 EXPECT_TRUE(GetArgs()->ContainsStrings(kEapCaCertPemProperty)); 219 if (GetArgs()->ContainsStrings(kEapCaCertPemProperty)) { 220 EXPECT_EQ(kCaCerts, GetArgs()->GetStrings(kEapCaCertPemProperty)); 221 } 222 EXPECT_EQ(kPort, GetArgs()->LookupString(kPortProperty, "")); 223 EXPECT_EQ(kPIN, GetArgs()->LookupString(kPINProperty, "")); 224 EXPECT_EQ(kPassword, GetArgs()->LookupString(kPasswordProperty, "")); 225 226 // Properties missing from the persistent store should be deleted. 227 EXPECT_FALSE(GetArgs()->ContainsString(kVPNHostProperty)); 228 EXPECT_FALSE(GetArgs()->ContainsStrings(kL2tpIpsecCaCertPemProperty)); 229 EXPECT_FALSE(GetArgs()->ContainsString(kPSKProperty)); 230 } 231 232 TEST_F(VPNDriverTest, Save) { 233 SetArg(kProviderTypeProperty, ""); 234 SetArg(kPINProperty, kPIN); 235 SetArg(kPortProperty, kPort); 236 SetArg(kPasswordProperty, kPassword); 237 SetArg(kOTPProperty, "987654"); 238 const vector<string> kCaCerts{ "cert0", "cert1" }; 239 SetArgArray(kEapCaCertPemProperty, kCaCerts); 240 MockStore storage; 241 EXPECT_CALL(storage, 242 SetStringList(kStorageID, kEapCaCertPemProperty, kCaCerts)) 243 .WillOnce(Return(true)); 244 EXPECT_CALL(storage, 245 SetString(kStorageID, kProviderTypeProperty, "")) 246 .WillOnce(Return(true)); 247 EXPECT_CALL(storage, SetString(kStorageID, kPortProperty, kPort)) 248 .WillOnce(Return(true)); 249 EXPECT_CALL(storage, SetString(kStorageID, kPINProperty, kPIN)) 250 .WillOnce(Return(true)); 251 EXPECT_CALL(storage, 252 SetCryptedString(kStorageID, kPasswordProperty, kPassword)) 253 .WillOnce(Return(true)); 254 EXPECT_CALL(storage, SetCryptedString(_, kOTPProperty, _)).Times(0); 255 EXPECT_CALL(storage, SetString(_, kOTPProperty, _)).Times(0); 256 EXPECT_CALL(storage, SetString(_, kEapCaCertPemProperty, _)).Times(0); 257 EXPECT_CALL(storage, DeleteKey(kStorageID, kEapCaCertPemProperty)).Times(0); 258 EXPECT_CALL(storage, DeleteKey(kStorageID, kProviderTypeProperty)) 259 .Times(0); 260 EXPECT_CALL(storage, DeleteKey(kStorageID, kL2tpIpsecCaCertPemProperty)); 261 EXPECT_CALL(storage, DeleteKey(kStorageID, kPSKProperty)); 262 EXPECT_CALL(storage, DeleteKey(kStorageID, kVPNHostProperty)); 263 EXPECT_TRUE(driver_.Save(&storage, kStorageID, true)); 264 } 265 266 TEST_F(VPNDriverTest, SaveNoCredentials) { 267 SetArg(kPasswordProperty, kPassword); 268 SetArg(kPSKProperty, ""); 269 MockStore storage; 270 EXPECT_CALL(storage, SetString(_, kPasswordProperty, _)).Times(0); 271 EXPECT_CALL(storage, SetCryptedString(_, kPasswordProperty, _)).Times(0); 272 EXPECT_CALL(storage, DeleteKey(kStorageID, _)).Times(AnyNumber()); 273 EXPECT_CALL(storage, DeleteKey(kStorageID, kPasswordProperty)); 274 EXPECT_CALL(storage, DeleteKey(kStorageID, kPSKProperty)); 275 EXPECT_CALL(storage, DeleteKey(kStorageID, kEapCaCertPemProperty)); 276 EXPECT_CALL(storage, DeleteKey(kStorageID, kL2tpIpsecCaCertPemProperty)); 277 EXPECT_TRUE(driver_.Save(&storage, kStorageID, false)); 278 } 279 280 TEST_F(VPNDriverTest, UnloadCredentials) { 281 SetArg(kOTPProperty, "654321"); 282 SetArg(kPasswordProperty, kPassword); 283 SetArg(kPortProperty, kPort); 284 driver_.UnloadCredentials(); 285 EXPECT_FALSE(GetArgs()->ContainsString(kOTPProperty)); 286 EXPECT_FALSE(GetArgs()->ContainsString(kPasswordProperty)); 287 EXPECT_EQ(kPort, GetArgs()->LookupString(kPortProperty, "")); 288 } 289 290 TEST_F(VPNDriverTest, InitPropertyStore) { 291 // Figure out if the store is actually hooked up to the driver argument 292 // KeyValueStore. 293 PropertyStore store; 294 driver_.InitPropertyStore(&store); 295 296 // An un-set property should not be readable. 297 { 298 Error error; 299 EXPECT_FALSE(store.GetStringProperty(kPortProperty, nullptr, &error)); 300 EXPECT_EQ(Error::kInvalidArguments, error.type()); 301 } 302 { 303 Error error; 304 EXPECT_FALSE( 305 store.GetStringsProperty(kEapCaCertPemProperty, nullptr, &error)); 306 EXPECT_EQ(Error::kInvalidArguments, error.type()); 307 } 308 EXPECT_FALSE(GetProviderPropertyString(store, kPortProperty, nullptr)); 309 EXPECT_FALSE( 310 GetProviderPropertyStrings(store, kEapCaCertPemProperty, nullptr)); 311 312 const string kProviderType = "boo"; 313 SetArg(kPortProperty, kPort); 314 SetArg(kPasswordProperty, kPassword); 315 SetArg(kProviderTypeProperty, kProviderType); 316 SetArg(kVPNHostProperty, ""); 317 const vector<string> kCaCerts{ "cert1" }; 318 SetArgArray(kEapCaCertPemProperty, kCaCerts); 319 SetArgArray(kL2tpIpsecCaCertPemProperty, vector<string>()); 320 321 // We should not be able to read a property out of the driver args using the 322 // key to the args directly. 323 { 324 Error error; 325 EXPECT_FALSE(store.GetStringProperty(kPortProperty, nullptr, &error)); 326 EXPECT_EQ(Error::kInvalidArguments, error.type()); 327 } 328 { 329 Error error; 330 EXPECT_FALSE( 331 store.GetStringsProperty(kEapCaCertPemProperty, nullptr, &error)); 332 EXPECT_EQ(Error::kInvalidArguments, error.type()); 333 } 334 335 // We should instead be able to find it within the "Provider" stringmap. 336 { 337 string value; 338 EXPECT_TRUE(GetProviderPropertyString(store, kPortProperty, &value)); 339 EXPECT_EQ(kPort, value); 340 } 341 { 342 vector<string> value; 343 EXPECT_TRUE(GetProviderPropertyStrings(store, kEapCaCertPemProperty, 344 &value)); 345 EXPECT_EQ(kCaCerts, value); 346 } 347 348 // We should be able to read empty properties from the "Provider" stringmap. 349 { 350 string value; 351 EXPECT_TRUE(GetProviderPropertyString(store, kVPNHostProperty, &value)); 352 EXPECT_TRUE(value.empty()); 353 } 354 { 355 vector<string> value; 356 EXPECT_TRUE(GetProviderPropertyStrings(store, kL2tpIpsecCaCertPemProperty, 357 &value)); 358 EXPECT_TRUE(value.empty()); 359 } 360 361 // Properties that start with the prefix "Provider." should be mapped to the 362 // name in the Properties dict with the prefix removed. 363 { 364 string value; 365 EXPECT_TRUE(GetProviderPropertyString(store, kTypeProperty, 366 &value)); 367 EXPECT_EQ(kProviderType, value); 368 } 369 370 // If we clear a property, we should no longer be able to find it. 371 { 372 Error error; 373 EXPECT_TRUE(store.ClearProperty(kPortProperty, &error)); 374 EXPECT_TRUE(error.IsSuccess()); 375 EXPECT_FALSE(GetProviderPropertyString(store, kPortProperty, nullptr)); 376 } 377 { 378 Error error; 379 EXPECT_TRUE(store.ClearProperty(kEapCaCertPemProperty, &error)); 380 EXPECT_TRUE(error.IsSuccess()); 381 EXPECT_FALSE(GetProviderPropertyStrings(store, kEapCaCertPemProperty, 382 nullptr)); 383 } 384 385 // A second attempt to clear this property should return an error. 386 { 387 Error error; 388 EXPECT_FALSE(store.ClearProperty(kPortProperty, &error)); 389 EXPECT_EQ(Error::kNotFound, error.type()); 390 } 391 { 392 Error error; 393 EXPECT_FALSE(store.ClearProperty(kEapCaCertPemProperty, &error)); 394 EXPECT_EQ(Error::kNotFound, error.type()); 395 } 396 397 // Test write only properties. 398 EXPECT_FALSE(GetProviderPropertyString(store, kPINProperty, nullptr)); 399 400 // Write properties to the driver args using the PropertyStore interface. 401 { 402 const string kValue = "some-value"; 403 Error error; 404 EXPECT_TRUE(store.SetStringProperty(kPINProperty, kValue, &error)); 405 EXPECT_EQ(kValue, GetArgs()->GetString(kPINProperty)); 406 } 407 { 408 const vector<string> kValue{ "some-value" }; 409 Error error; 410 EXPECT_TRUE(store.SetStringsProperty(kEapCaCertPemProperty, kValue, 411 &error)); 412 EXPECT_EQ(kValue, GetArgs()->GetStrings(kEapCaCertPemProperty)); 413 } 414 } 415 416 TEST_F(VPNDriverTest, ConnectTimeout) { 417 EXPECT_EQ(&dispatcher_, dispatcher()); 418 EXPECT_TRUE(connect_timeout_callback().IsCancelled()); 419 EXPECT_FALSE(IsConnectTimeoutStarted()); 420 StartConnectTimeout(0); 421 EXPECT_FALSE(connect_timeout_callback().IsCancelled()); 422 EXPECT_TRUE(IsConnectTimeoutStarted()); 423 set_dispatcher(nullptr); 424 StartConnectTimeout(0); // Expect no crash. 425 dispatcher_.DispatchPendingEvents(); 426 EXPECT_TRUE(connect_timeout_callback().IsCancelled()); 427 EXPECT_FALSE(IsConnectTimeoutStarted()); 428 } 429 430 TEST_F(VPNDriverTest, StartStopConnectTimeout) { 431 EXPECT_FALSE(IsConnectTimeoutStarted()); 432 EXPECT_EQ(0, connect_timeout_seconds()); 433 const int kTimeout = 123; 434 StartConnectTimeout(kTimeout); 435 EXPECT_TRUE(IsConnectTimeoutStarted()); 436 EXPECT_EQ(kTimeout, connect_timeout_seconds()); 437 StartConnectTimeout(kTimeout - 20); 438 EXPECT_EQ(kTimeout, connect_timeout_seconds()); 439 StopConnectTimeout(); 440 EXPECT_FALSE(IsConnectTimeoutStarted()); 441 EXPECT_EQ(0, connect_timeout_seconds()); 442 } 443 444 } // namespace shill 445