Home | History | Annotate | Download | only in apmanager
      1 //
      2 // Copyright (C) 2014 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 "apmanager/config.h"
     18 
     19 #include <string>
     20 
     21 #include <base/strings/string_util.h>
     22 #include <base/strings/stringprintf.h>
     23 #include <gmock/gmock.h>
     24 #include <gtest/gtest.h>
     25 
     26 #if !defined(__ANDROID__)
     27 #include <chromeos/dbus/service_constants.h>
     28 #else
     29 #include "dbus/apmanager/dbus-constants.h"
     30 #endif
     31 
     32 #include "apmanager/error.h"
     33 #include "apmanager/fake_config_adaptor.h"
     34 #include "apmanager/fake_device_adaptor.h"
     35 #include "apmanager/mock_control.h"
     36 #include "apmanager/mock_device.h"
     37 #include "apmanager/mock_manager.h"
     38 
     39 using ::testing::_;
     40 using ::testing::Mock;
     41 using ::testing::Return;
     42 using ::testing::ReturnNew;
     43 using ::testing::SetArgumentPointee;
     44 namespace apmanager {
     45 
     46 namespace {
     47 
     48 const char kSsid[] = "TestSsid";
     49 const char kInterface[] = "uap0";
     50 const char kBridgeInterface[] = "br0";
     51 const char kControlInterfacePath[] = "/var/run/apmanager/hostapd/ctrl_iface";
     52 const char kPassphrase[] = "Passphrase";
     53 const char k24GHzHTCapab[] = "[LDPC SMPS-STATIC GF SHORT-GI-20]";
     54 const char k5GHzHTCapab[] =
     55     "[LDPC HT40+ SMPS-STATIC GF SHORT-GI-20 SHORT-GI-40]";
     56 
     57 const uint16_t k24GHzChannel = 6;
     58 const uint16_t k5GHzChannel = 36;
     59 
     60 const char kExpected80211gConfigContent[] = "ssid=TestSsid\n"
     61                                             "channel=6\n"
     62                                             "interface=uap0\n"
     63                                             "hw_mode=g\n"
     64                                             "driver=nl80211\n"
     65                                             "fragm_threshold=2346\n"
     66                                             "rts_threshold=2347\n";
     67 
     68 const char kExpected80211gBridgeConfigContent[] = "ssid=TestSsid\n"
     69                                                   "bridge=br0\n"
     70                                                   "channel=6\n"
     71                                                   "interface=uap0\n"
     72                                                   "hw_mode=g\n"
     73                                                   "driver=nl80211\n"
     74                                                   "fragm_threshold=2346\n"
     75                                                   "rts_threshold=2347\n";
     76 
     77 const char kExpected80211gCtrlIfaceConfigContent[] =
     78     "ssid=TestSsid\n"
     79     "channel=6\n"
     80     "interface=uap0\n"
     81     "hw_mode=g\n"
     82     "ctrl_interface=/var/run/apmanager/hostapd/ctrl_iface\n"
     83 #if !defined(__ANDROID__)
     84     "ctrl_interface_group=apmanager\n"
     85 #else
     86     "ctrl_interface_group=system\n"
     87 #endif  // __ANDROID__
     88     "driver=nl80211\n"
     89     "fragm_threshold=2346\n"
     90     "rts_threshold=2347\n";
     91 
     92 const char kExpected80211n5GHzConfigContent[] =
     93     "ssid=TestSsid\n"
     94     "channel=36\n"
     95     "interface=uap0\n"
     96     "ieee80211n=1\n"
     97     "ht_capab=[LDPC HT40+ SMPS-STATIC GF SHORT-GI-20 SHORT-GI-40]\n"
     98     "hw_mode=a\n"
     99     "driver=nl80211\n"
    100     "fragm_threshold=2346\n"
    101     "rts_threshold=2347\n";
    102 
    103 const char kExpected80211n24GHzConfigContent[] =
    104     "ssid=TestSsid\n"
    105     "channel=6\n"
    106     "interface=uap0\n"
    107     "ieee80211n=1\n"
    108     "ht_capab=[LDPC SMPS-STATIC GF SHORT-GI-20]\n"
    109     "hw_mode=g\n"
    110     "driver=nl80211\n"
    111     "fragm_threshold=2346\n"
    112     "rts_threshold=2347\n";
    113 
    114 const char kExpectedRsnConfigContent[] = "ssid=TestSsid\n"
    115                                          "channel=6\n"
    116                                          "interface=uap0\n"
    117                                          "hw_mode=g\n"
    118                                          "wpa=2\n"
    119                                          "rsn_pairwise=CCMP\n"
    120                                          "wpa_key_mgmt=WPA-PSK\n"
    121                                          "wpa_passphrase=Passphrase\n"
    122                                          "driver=nl80211\n"
    123                                          "fragm_threshold=2346\n"
    124                                          "rts_threshold=2347\n";
    125 
    126 }  // namespace
    127 
    128 class ConfigTest : public testing::Test {
    129  public:
    130   ConfigTest()
    131       : manager_(&control_interface_) {
    132     ON_CALL(control_interface_, CreateDeviceAdaptorRaw())
    133         .WillByDefault(ReturnNew<FakeDeviceAdaptor>());
    134     ON_CALL(control_interface_, CreateConfigAdaptorRaw())
    135         .WillByDefault(ReturnNew<FakeConfigAdaptor>());
    136     // Defer creation of Config object to allow ControlInterface to setup
    137     // expectations for generating fake adaptors.
    138     config_.reset(new Config(&manager_, 0));
    139   }
    140 
    141   void SetupDevice(const std::string& interface) {
    142     // Setup mock device.
    143     device_ = new MockDevice(&manager_);
    144     device_->SetPreferredApInterface(interface);
    145     EXPECT_CALL(manager_, GetDeviceFromInterfaceName(interface))
    146         .WillRepeatedly(Return(device_));
    147   }
    148 
    149   void VerifyError(const Error& error,
    150                    Error::Type expected_type,
    151                    const std::string& expected_message_start) {
    152     EXPECT_EQ(expected_type, error.type());
    153     EXPECT_TRUE(base::StartsWith(error.message(), expected_message_start,
    154                                  base::CompareCase::INSENSITIVE_ASCII));
    155   }
    156 
    157  protected:
    158   MockControl control_interface_;
    159   MockManager manager_;
    160   scoped_refptr<MockDevice> device_;
    161   std::unique_ptr<Config> config_;
    162 };
    163 
    164 TEST_F(ConfigTest, GetFrequencyFromChannel) {
    165   uint32_t frequency;
    166   // Invalid channel.
    167   EXPECT_FALSE(Config::GetFrequencyFromChannel(0, &frequency));
    168   EXPECT_FALSE(Config::GetFrequencyFromChannel(166, &frequency));
    169   EXPECT_FALSE(Config::GetFrequencyFromChannel(14, &frequency));
    170   EXPECT_FALSE(Config::GetFrequencyFromChannel(33, &frequency));
    171 
    172   // Valid channel.
    173   const uint32_t kChannel1Frequency = 2412;
    174   const uint32_t kChannel13Frequency = 2472;
    175   const uint32_t kChannel34Frequency = 5170;
    176   const uint32_t kChannel165Frequency = 5825;
    177   EXPECT_TRUE(Config::GetFrequencyFromChannel(1, &frequency));
    178   EXPECT_EQ(kChannel1Frequency, frequency);
    179   EXPECT_TRUE(Config::GetFrequencyFromChannel(13, &frequency));
    180   EXPECT_EQ(kChannel13Frequency, frequency);
    181   EXPECT_TRUE(Config::GetFrequencyFromChannel(34, &frequency));
    182   EXPECT_EQ(kChannel34Frequency, frequency);
    183   EXPECT_TRUE(Config::GetFrequencyFromChannel(165, &frequency));
    184   EXPECT_EQ(kChannel165Frequency, frequency);
    185 }
    186 
    187 TEST_F(ConfigTest, ValidateSsid) {
    188   Error error;
    189   // SSID must contain between 1 and 32 characters.
    190   EXPECT_TRUE(config_->ValidateSsid(&error, "s"));
    191   EXPECT_TRUE(config_->ValidateSsid(&error, std::string(32, 'c')));
    192   EXPECT_FALSE(config_->ValidateSsid(&error, ""));
    193   EXPECT_FALSE(config_->ValidateSsid(&error, std::string(33, 'c')));
    194 }
    195 
    196 TEST_F(ConfigTest, ValidateSecurityMode) {
    197   Error error;
    198   EXPECT_TRUE(config_->ValidateSecurityMode(&error, kSecurityModeNone));
    199   EXPECT_TRUE(config_->ValidateSecurityMode(&error, kSecurityModeRSN));
    200   EXPECT_FALSE(config_->ValidateSecurityMode(&error, "InvalidSecurityMode"));
    201 }
    202 
    203 TEST_F(ConfigTest, ValidatePassphrase) {
    204   Error error;
    205   // Passpharse must contain between 8 and 63 characters.
    206   EXPECT_TRUE(config_->ValidatePassphrase(&error, std::string(8, 'c')));
    207   EXPECT_TRUE(config_->ValidatePassphrase(&error, std::string(63, 'c')));
    208   EXPECT_FALSE(config_->ValidatePassphrase(&error, std::string(7, 'c')));
    209   EXPECT_FALSE(config_->ValidatePassphrase(&error, std::string(64, 'c')));
    210 }
    211 
    212 TEST_F(ConfigTest, ValidateHwMode) {
    213   Error error;
    214   EXPECT_TRUE(config_->ValidateHwMode(&error, kHwMode80211a));
    215   EXPECT_TRUE(config_->ValidateHwMode(&error, kHwMode80211b));
    216   EXPECT_TRUE(config_->ValidateHwMode(&error, kHwMode80211g));
    217   EXPECT_TRUE(config_->ValidateHwMode(&error, kHwMode80211n));
    218   EXPECT_TRUE(config_->ValidateHwMode(&error, kHwMode80211ac));
    219   EXPECT_FALSE(config_->ValidateSecurityMode(&error, "InvalidHwMode"));
    220 }
    221 
    222 TEST_F(ConfigTest, ValidateOperationMode) {
    223   Error error;
    224   EXPECT_TRUE(config_->ValidateOperationMode(&error, kOperationModeServer));
    225   EXPECT_TRUE(config_->ValidateOperationMode(&error, kOperationModeBridge));
    226   EXPECT_FALSE(config_->ValidateOperationMode(&error, "InvalidMode"));
    227 }
    228 
    229 TEST_F(ConfigTest, ValidateChannel) {
    230   Error error;
    231   EXPECT_TRUE(config_->ValidateChannel(&error, 1));
    232   EXPECT_TRUE(config_->ValidateChannel(&error, 13));
    233   EXPECT_TRUE(config_->ValidateChannel(&error, 34));
    234   EXPECT_TRUE(config_->ValidateChannel(&error, 165));
    235   EXPECT_FALSE(config_->ValidateChannel(&error, 0));
    236   EXPECT_FALSE(config_->ValidateChannel(&error, 14));
    237   EXPECT_FALSE(config_->ValidateChannel(&error, 33));
    238   EXPECT_FALSE(config_->ValidateChannel(&error, 166));
    239 }
    240 
    241 TEST_F(ConfigTest, NoSsid) {
    242   config_->SetChannel(k24GHzChannel);
    243   config_->SetHwMode(kHwMode80211g);
    244   config_->SetInterfaceName(kInterface);
    245 
    246   std::string config_content;
    247   Error error;
    248   EXPECT_FALSE(config_->GenerateConfigFile(&error, &config_content));
    249   VerifyError(error, Error::kInvalidConfiguration, "SSID not specified");
    250 }
    251 
    252 TEST_F(ConfigTest, NoInterface) {
    253   // Basic 80211.g configuration.
    254   config_->SetSsid(kSsid);
    255   config_->SetChannel(k24GHzChannel);
    256   config_->SetHwMode(kHwMode80211g);
    257 
    258   // No device available, fail to generate config file.
    259   Error error;
    260   std::string config_content;
    261   EXPECT_CALL(manager_, GetAvailableDevice()).WillOnce(Return(nullptr));
    262   EXPECT_FALSE(config_->GenerateConfigFile(&error, &config_content));
    263   VerifyError(error, Error::kInternalError, "No device available");
    264   Mock::VerifyAndClearExpectations(&manager_);
    265 
    266   // Device available, config file should be generated without any problem.
    267   scoped_refptr<MockDevice> device = new MockDevice(&manager_);
    268   device->SetPreferredApInterface(kInterface);
    269   error.Reset();
    270   EXPECT_CALL(manager_, GetAvailableDevice()).WillOnce(Return(device));
    271   EXPECT_TRUE(config_->GenerateConfigFile(&error, &config_content));
    272   EXPECT_NE(std::string::npos, config_content.find(
    273                                    kExpected80211gConfigContent))
    274       << "Expected to find the following config...\n"
    275       << kExpected80211gConfigContent << "..within content...\n"
    276       << config_content;
    277   EXPECT_TRUE(error.IsSuccess());
    278   Mock::VerifyAndClearExpectations(&manager_);
    279 }
    280 
    281 TEST_F(ConfigTest, InvalidInterface) {
    282   // Basic 80211.g configuration.
    283   config_->SetSsid(kSsid);
    284   config_->SetChannel(k24GHzChannel);
    285   config_->SetHwMode(kHwMode80211g);
    286   config_->SetInterfaceName(kInterface);
    287 
    288   // Unable to find the device, fail to generate config file.
    289   Error error;
    290   std::string config_content;
    291   EXPECT_CALL(manager_, GetDeviceFromInterfaceName(kInterface))
    292       .WillOnce(Return(nullptr));
    293   EXPECT_FALSE(config_->GenerateConfigFile(&error, &config_content));
    294   VerifyError(error,
    295               Error::kInvalidConfiguration,
    296               "Unable to find device for the specified interface");
    297   Mock::VerifyAndClearExpectations(&manager_);
    298 }
    299 
    300 TEST_F(ConfigTest, BridgeMode) {
    301   config_->SetSsid(kSsid);
    302   config_->SetChannel(k24GHzChannel);
    303   config_->SetHwMode(kHwMode80211g);
    304   config_->SetInterfaceName(kInterface);
    305   config_->SetOperationMode(kOperationModeBridge);
    306 
    307   // Bridge interface required for bridge mode.
    308   Error error;
    309   std::string config_content;
    310   EXPECT_FALSE(config_->GenerateConfigFile(&error, &config_content));
    311   VerifyError(
    312       error, Error::kInvalidConfiguration, "Bridge interface not specified");
    313 
    314   // Set bridge interface, config file should be generated without error.
    315   config_->SetBridgeInterface(kBridgeInterface);
    316   // Setup mock device.
    317   SetupDevice(kInterface);
    318   error.Reset();
    319   std::string config_content1;
    320   EXPECT_TRUE(config_->GenerateConfigFile(&error, &config_content1));
    321   EXPECT_NE(std::string::npos, config_content1.find(
    322                                    kExpected80211gBridgeConfigContent))
    323       << "Expected to find the following config...\n"
    324       << kExpected80211gBridgeConfigContent << "..within content...\n"
    325       << config_content1;
    326   EXPECT_TRUE(error.IsSuccess());
    327 }
    328 
    329 TEST_F(ConfigTest, 80211gConfig) {
    330   config_->SetSsid(kSsid);
    331   config_->SetChannel(k24GHzChannel);
    332   config_->SetHwMode(kHwMode80211g);
    333   config_->SetInterfaceName(kInterface);
    334 
    335   // Setup mock device.
    336   SetupDevice(kInterface);
    337 
    338   std::string config_content;
    339   Error error;
    340   EXPECT_TRUE(config_->GenerateConfigFile(&error, &config_content));
    341   EXPECT_NE(std::string::npos, config_content.find(
    342                                    kExpected80211gConfigContent))
    343       << "Expected to find the following config...\n"
    344       << kExpected80211gConfigContent << "..within content...\n"
    345       << config_content;
    346   EXPECT_TRUE(error.IsSuccess());
    347 }
    348 
    349 TEST_F(ConfigTest, 80211gConfigWithControlInterface) {
    350   config_->SetSsid(kSsid);
    351   config_->SetChannel(k24GHzChannel);
    352   config_->SetHwMode(kHwMode80211g);
    353   config_->SetInterfaceName(kInterface);
    354   config_->set_control_interface(kControlInterfacePath);
    355 
    356   // Setup mock device.
    357   SetupDevice(kInterface);
    358 
    359   std::string config_content;
    360   Error error;
    361   EXPECT_TRUE(config_->GenerateConfigFile(&error, &config_content));
    362   EXPECT_NE(std::string::npos, config_content.find(
    363                                    kExpected80211gCtrlIfaceConfigContent))
    364       << "Expected to find the following config...\n"
    365       << kExpected80211gCtrlIfaceConfigContent << "..within content...\n"
    366       << config_content;
    367   EXPECT_TRUE(error.IsSuccess());
    368 }
    369 
    370 TEST_F(ConfigTest, 80211nConfig) {
    371   config_->SetSsid(kSsid);
    372   config_->SetHwMode(kHwMode80211n);
    373   config_->SetInterfaceName(kInterface);
    374 
    375   // Setup mock device.
    376   SetupDevice(kInterface);
    377 
    378   // 5GHz channel.
    379   config_->SetChannel(k5GHzChannel);
    380   std::string ghz5_config_content;
    381   Error error;
    382   std::string ht_capab_5ghz(k5GHzHTCapab);
    383   EXPECT_CALL(*device_.get(), GetHTCapability(k5GHzChannel, _))
    384       .WillOnce(DoAll(SetArgumentPointee<1>(ht_capab_5ghz), Return(true)));
    385   EXPECT_TRUE(config_->GenerateConfigFile(&error, &ghz5_config_content));
    386   EXPECT_NE(std::string::npos, ghz5_config_content.find(
    387                                    kExpected80211n5GHzConfigContent))
    388       << "Expected to find the following config...\n"
    389       << kExpected80211n5GHzConfigContent << "..within content...\n"
    390       << ghz5_config_content;
    391   EXPECT_TRUE(error.IsSuccess());
    392   Mock::VerifyAndClearExpectations(device_.get());
    393 
    394   // 2.4GHz channel.
    395   config_->SetChannel(k24GHzChannel);
    396   std::string ghz24_config_content;
    397   error.Reset();
    398   std::string ht_capab_24ghz(k24GHzHTCapab);
    399   EXPECT_CALL(*device_.get(), GetHTCapability(k24GHzChannel, _))
    400       .WillOnce(DoAll(SetArgumentPointee<1>(ht_capab_24ghz), Return(true)));
    401   EXPECT_TRUE(config_->GenerateConfigFile(&error, &ghz24_config_content));
    402   EXPECT_NE(std::string::npos, ghz24_config_content.find(
    403                                    kExpected80211n24GHzConfigContent))
    404       << "Expected to find the following config...\n"
    405       << kExpected80211n24GHzConfigContent << "..within content...\n"
    406       << ghz24_config_content;
    407   EXPECT_TRUE(error.IsSuccess());
    408   Mock::VerifyAndClearExpectations(device_.get());
    409 }
    410 
    411 TEST_F(ConfigTest, RsnConfig) {
    412   config_->SetSsid(kSsid);
    413   config_->SetChannel(k24GHzChannel);
    414   config_->SetHwMode(kHwMode80211g);
    415   config_->SetInterfaceName(kInterface);
    416   config_->SetSecurityMode(kSecurityModeRSN);
    417 
    418   // Setup mock device.
    419   SetupDevice(kInterface);
    420 
    421   // Failed due to no passphrase specified.
    422   std::string config_content;
    423   Error error;
    424   EXPECT_FALSE(config_->GenerateConfigFile(&error, &config_content));
    425   VerifyError(
    426       error,
    427       Error::kInvalidConfiguration,
    428       base::StringPrintf("Passphrase not set for security mode: %s",
    429                          kSecurityModeRSN));
    430 
    431   error.Reset();
    432   config_->SetPassphrase(kPassphrase);
    433   EXPECT_TRUE(config_->GenerateConfigFile(&error, &config_content));
    434   EXPECT_NE(std::string::npos, config_content.find(
    435                                    kExpectedRsnConfigContent))
    436       << "Expected to find the following config...\n"
    437       << kExpectedRsnConfigContent << "..within content...\n"
    438       << config_content;
    439   EXPECT_TRUE(error.IsSuccess());
    440 }
    441 
    442 }  // namespace apmanager
    443