• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
ConfigTest()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 
SetupDevice(const std::string & interface)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 
VerifyError(const Error & error,Error::Type expected_type,const std::string & expected_message_start)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 
TEST_F(ConfigTest,GetFrequencyFromChannel)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 
TEST_F(ConfigTest,ValidateSsid)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 
TEST_F(ConfigTest,ValidateSecurityMode)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 
TEST_F(ConfigTest,ValidatePassphrase)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 
TEST_F(ConfigTest,ValidateHwMode)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 
TEST_F(ConfigTest,ValidateOperationMode)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 
TEST_F(ConfigTest,ValidateChannel)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 
TEST_F(ConfigTest,NoSsid)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 
TEST_F(ConfigTest,NoInterface)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 
TEST_F(ConfigTest,InvalidInterface)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 
TEST_F(ConfigTest,BridgeMode)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 
TEST_F(ConfigTest,RsnConfig)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