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