Home | History | Annotate | Download | only in vpn
      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