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