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 <base/strings/stringprintf.h>
20
21 #if !defined(__ANDROID__)
22 #include <chromeos/dbus/service_constants.h>
23 #else
24 #include <dbus/apmanager/dbus-constants.h>
25 #endif // __ANDROID__
26
27 #include "apmanager/error.h"
28 #include "apmanager/daemon.h"
29 #include "apmanager/device.h"
30 #include "apmanager/manager.h"
31
32 using std::string;
33
34 namespace apmanager {
35
36 // static
37 const char Config::kHostapdConfigKeyBridgeInterface[] = "bridge";
38 const char Config::kHostapdConfigKeyChannel[] = "channel";
39 const char Config::kHostapdConfigKeyControlInterface[] = "ctrl_interface";
40 const char Config::kHostapdConfigKeyControlInterfaceGroup[] =
41 "ctrl_interface_group";
42 const char Config::kHostapdConfigKeyDriver[] = "driver";
43 const char Config::kHostapdConfigKeyFragmThreshold[] = "fragm_threshold";
44 const char Config::kHostapdConfigKeyHTCapability[] = "ht_capab";
45 const char Config::kHostapdConfigKeyHwMode[] = "hw_mode";
46 const char Config::kHostapdConfigKeyIeee80211ac[] = "ieee80211ac";
47 const char Config::kHostapdConfigKeyIeee80211n[] = "ieee80211n";
48 const char Config::kHostapdConfigKeyIgnoreBroadcastSsid[] =
49 "ignore_broadcast_ssid";
50 const char Config::kHostapdConfigKeyInterface[] = "interface";
51 const char Config::kHostapdConfigKeyRsnPairwise[] = "rsn_pairwise";
52 const char Config::kHostapdConfigKeyRtsThreshold[] = "rts_threshold";
53 const char Config::kHostapdConfigKeySsid[] = "ssid";
54 const char Config::kHostapdConfigKeyWepDefaultKey[] = "wep_default_key";
55 const char Config::kHostapdConfigKeyWepKey0[] = "wep_key0";
56 const char Config::kHostapdConfigKeyWpa[] = "wpa";
57 const char Config::kHostapdConfigKeyWpaKeyMgmt[] = "wpa_key_mgmt";
58 const char Config::kHostapdConfigKeyWpaPassphrase[] = "wpa_passphrase";
59
60 const char Config::kHostapdHwMode80211a[] = "a";
61 const char Config::kHostapdHwMode80211b[] = "b";
62 const char Config::kHostapdHwMode80211g[] = "g";
63
64 // static
65 const uint16_t Config::kPropertyDefaultChannel = 6;
66 const uint16_t Config::kPropertyDefaultServerAddressIndex = 0;
67 const bool Config::kPropertyDefaultHiddenNetwork = false;
68
69 // static
70 const char Config::kHostapdDefaultDriver[] = "nl80211";
71 const char Config::kHostapdDefaultRsnPairwise[] = "CCMP";
72 const char Config::kHostapdDefaultWpaKeyMgmt[] = "WPA-PSK";
73 // Fragmentation threshold: disabled.
74 const int Config::kHostapdDefaultFragmThreshold = 2346;
75 // RTS threshold: disabled.
76 const int Config::kHostapdDefaultRtsThreshold = 2347;
77
78 // static
79 const uint16_t Config::kBand24GHzChannelLow = 1;
80 const uint16_t Config::kBand24GHzChannelHigh = 13;
81 const uint32_t Config::kBand24GHzBaseFrequency = 2412;
82 const uint16_t Config::kBand5GHzChannelLow = 34;
83 const uint16_t Config::kBand5GHzChannelHigh = 165;
84 const uint16_t Config::kBand5GHzBaseFrequency = 5170;
85
86 // static
87 const int Config::kSsidMinLength = 1;
88 const int Config::kSsidMaxLength = 32;
89 const int Config::kPassphraseMinLength = 8;
90 const int Config::kPassphraseMaxLength = 63;
91
Config(Manager * manager,int service_identifier)92 Config::Config(Manager* manager, int service_identifier)
93 : manager_(manager),
94 adaptor_(
95 manager->control_interface()->CreateConfigAdaptor(
96 this, service_identifier)) {
97 // Initialize default configuration values.
98 SetSecurityMode(kSecurityModeNone);
99 SetHwMode(kHwMode80211g);
100 SetOperationMode(kOperationModeServer);
101 SetServerAddressIndex(kPropertyDefaultServerAddressIndex);
102 SetChannel(kPropertyDefaultChannel);
103 SetHiddenNetwork(kPropertyDefaultHiddenNetwork);
104 SetFullDeviceControl(true);
105 }
106
~Config()107 Config::~Config() {}
108
109 // static.
GetFrequencyFromChannel(uint16_t channel,uint32_t * freq)110 bool Config::GetFrequencyFromChannel(uint16_t channel, uint32_t* freq) {
111 bool ret_value = true;
112 if (channel >= kBand24GHzChannelLow && channel <= kBand24GHzChannelHigh) {
113 *freq = kBand24GHzBaseFrequency + (channel - kBand24GHzChannelLow) * 5;
114 } else if (channel >= kBand5GHzChannelLow &&
115 channel <= kBand5GHzChannelHigh) {
116 *freq = kBand5GHzBaseFrequency + (channel - kBand5GHzChannelLow) * 5;
117 } else {
118 ret_value = false;
119 }
120 return ret_value;
121 }
122
ValidateSsid(Error * error,const string & value)123 bool Config::ValidateSsid(Error* error, const string& value) {
124 if (value.length() < kSsidMinLength || value.length() > kSsidMaxLength) {
125 Error::PopulateAndLog(
126 error,
127 Error::kInvalidArguments,
128 base::StringPrintf("SSID must contain between %d and %d characters",
129 kSsidMinLength, kSsidMaxLength),
130 FROM_HERE);
131 return false;
132 }
133 return true;
134 }
135
ValidateSecurityMode(Error * error,const string & value)136 bool Config::ValidateSecurityMode(Error* error, const string& value) {
137 if (value != kSecurityModeNone && value != kSecurityModeRSN) {
138 Error::PopulateAndLog(
139 error,
140 Error::kInvalidArguments,
141 base::StringPrintf("Invalid/unsupported security mode [%s]",
142 value.c_str()),
143 FROM_HERE);
144 return false;
145 }
146 return true;
147 }
148
ValidatePassphrase(Error * error,const string & value)149 bool Config::ValidatePassphrase(Error* error, const string& value) {
150 if (value.length() < kPassphraseMinLength ||
151 value.length() > kPassphraseMaxLength) {
152 Error::PopulateAndLog(
153 error,
154 Error::kInvalidArguments,
155 base::StringPrintf("Passphrase must contain between %d and %d characters",
156 kPassphraseMinLength, kPassphraseMaxLength),
157 FROM_HERE);
158
159 return false;
160 }
161 return true;
162 }
163
ValidateHwMode(Error * error,const string & value)164 bool Config::ValidateHwMode(Error* error, const string& value) {
165 if (value != kHwMode80211a && value != kHwMode80211b &&
166 value != kHwMode80211g && value != kHwMode80211n &&
167 value != kHwMode80211ac) {
168 Error::PopulateAndLog(
169 error,
170 Error::kInvalidArguments,
171 base::StringPrintf("Invalid HW mode [%s]", value.c_str()),
172 FROM_HERE);
173 return false;
174 }
175 return true;
176 }
177
ValidateOperationMode(Error * error,const string & value)178 bool Config::ValidateOperationMode(Error* error, const string& value) {
179 if (value != kOperationModeServer && value != kOperationModeBridge) {
180 Error::PopulateAndLog(
181 error,
182 Error::kInvalidArguments,
183 base::StringPrintf("Invalid operation mode [%s]", value.c_str()),
184 FROM_HERE);
185 return false;
186 }
187 return true;
188 }
189
ValidateChannel(Error * error,const uint16_t & value)190 bool Config::ValidateChannel(Error* error, const uint16_t& value) {
191 if ((value >= kBand24GHzChannelLow && value <= kBand24GHzChannelHigh) ||
192 (value >= kBand5GHzChannelLow && value <= kBand5GHzChannelHigh)) {
193 return true;
194 }
195 Error::PopulateAndLog(error,
196 Error::kInvalidArguments,
197 base::StringPrintf("Invalid channel [%d]", value),
198 FROM_HERE);
199 return false;
200 }
201
GenerateConfigFile(Error * error,string * config_str)202 bool Config::GenerateConfigFile(Error* error, string* config_str) {
203 // SSID.
204 string ssid = GetSsid();
205 if (ssid.empty()) {
206 Error::PopulateAndLog(error,
207 Error::kInvalidConfiguration,
208 "SSID not specified",
209 FROM_HERE);
210 return false;
211 }
212 base::StringAppendF(
213 config_str, "%s=%s\n", kHostapdConfigKeySsid, ssid.c_str());
214
215 // Bridge interface is required for bridge mode operation.
216 if (GetOperationMode() == kOperationModeBridge) {
217 if (GetBridgeInterface().empty()) {
218 Error::PopulateAndLog(
219 error,
220 Error::kInvalidConfiguration,
221 "Bridge interface not specified, required for bridge mode",
222 FROM_HERE);
223 return false;
224 }
225 base::StringAppendF(config_str,
226 "%s=%s\n",
227 kHostapdConfigKeyBridgeInterface,
228 GetBridgeInterface().c_str());
229 }
230
231 // Channel.
232 base::StringAppendF(
233 config_str, "%s=%d\n", kHostapdConfigKeyChannel, GetChannel());
234
235 // Interface.
236 if (!AppendInterface(error, config_str)) {
237 return false;
238 }
239
240 // Hardware mode.
241 if (!AppendHwMode(error, config_str)) {
242 return false;
243 }
244
245 // Security mode configurations.
246 if (!AppendSecurityMode(error, config_str)) {
247 return false;
248 }
249
250 // Control interface.
251 if (!control_interface_.empty()) {
252 base::StringAppendF(config_str,
253 "%s=%s\n",
254 kHostapdConfigKeyControlInterface,
255 control_interface_.c_str());
256 base::StringAppendF(config_str,
257 "%s=%s\n",
258 kHostapdConfigKeyControlInterfaceGroup,
259 Daemon::kAPManagerGroupName);
260 }
261
262 // Hostapd default configurations.
263 if (!AppendHostapdDefaults(error, config_str)) {
264 return false;
265 }
266
267 return true;
268 }
269
ClaimDevice()270 bool Config::ClaimDevice() {
271 if (!device_) {
272 LOG(ERROR) << "Failed to claim device: device doesn't exist.";
273 return false;
274 }
275 return device_->ClaimDevice(GetFullDeviceControl());
276 }
277
ReleaseDevice()278 bool Config::ReleaseDevice() {
279 if (!device_) {
280 LOG(ERROR) << "Failed to release device: device doesn't exist.";
281 return false;
282 }
283 return device_->ReleaseDevice();
284 }
285
SetSsid(const string & ssid)286 void Config::SetSsid(const string& ssid) {
287 adaptor_->SetSsid(ssid);
288 }
289
GetSsid() const290 string Config::GetSsid() const {
291 return adaptor_->GetSsid();
292 }
293
SetInterfaceName(const std::string & interface_name)294 void Config::SetInterfaceName(const std::string& interface_name) {
295 adaptor_->SetInterfaceName(interface_name);
296 }
297
GetInterfaceName() const298 string Config::GetInterfaceName() const {
299 return adaptor_->GetInterfaceName();
300 }
301
SetSecurityMode(const std::string & mode)302 void Config::SetSecurityMode(const std::string& mode) {
303 adaptor_->SetSecurityMode(mode);
304 }
305
GetSecurityMode() const306 string Config::GetSecurityMode() const {
307 return adaptor_->GetSecurityMode();
308 }
309
SetPassphrase(const std::string & passphrase)310 void Config::SetPassphrase(const std::string& passphrase) {
311 adaptor_->SetPassphrase(passphrase);
312 }
313
GetPassphrase() const314 string Config::GetPassphrase() const {
315 return adaptor_->GetPassphrase();
316 }
317
SetHwMode(const std::string & hw_mode)318 void Config::SetHwMode(const std::string& hw_mode) {
319 adaptor_->SetHwMode(hw_mode);
320 }
321
GetHwMode() const322 string Config::GetHwMode() const {
323 return adaptor_->GetHwMode();
324 }
325
SetOperationMode(const std::string & op_mode)326 void Config::SetOperationMode(const std::string& op_mode) {
327 adaptor_->SetOperationMode(op_mode);
328 }
329
GetOperationMode() const330 string Config::GetOperationMode() const {
331 return adaptor_->GetOperationMode();
332 }
333
SetChannel(uint16_t channel)334 void Config::SetChannel(uint16_t channel) {
335 adaptor_->SetChannel(channel);
336 }
337
GetChannel() const338 uint16_t Config::GetChannel() const {
339 return adaptor_->GetChannel();
340 }
341
SetHiddenNetwork(bool hidden_network)342 void Config::SetHiddenNetwork(bool hidden_network) {
343 adaptor_->SetHiddenNetwork(hidden_network);
344 }
345
GetHiddenNetwork() const346 bool Config::GetHiddenNetwork() const {
347 return adaptor_->GetHiddenNetwork();
348 }
349
SetBridgeInterface(const std::string & interface_name)350 void Config::SetBridgeInterface(const std::string& interface_name) {
351 adaptor_->SetBridgeInterface(interface_name);
352 }
353
GetBridgeInterface() const354 string Config::GetBridgeInterface() const {
355 return adaptor_->GetBridgeInterface();
356 }
357
SetServerAddressIndex(uint16_t index)358 void Config::SetServerAddressIndex(uint16_t index) {
359 adaptor_->SetServerAddressIndex(index);
360 }
361
GetServerAddressIndex() const362 uint16_t Config::GetServerAddressIndex() const {
363 return adaptor_->GetServerAddressIndex();
364 }
365
SetFullDeviceControl(bool full_control)366 void Config::SetFullDeviceControl(bool full_control) {
367 adaptor_->SetFullDeviceControl(full_control);
368 }
369
GetFullDeviceControl() const370 bool Config::GetFullDeviceControl() const {
371 return adaptor_->GetFullDeviceControl();
372 }
373
AppendHwMode(Error * error,string * config_str)374 bool Config::AppendHwMode(Error* error, string* config_str) {
375 string hw_mode = GetHwMode();
376 string hostapd_hw_mode;
377 if (hw_mode == kHwMode80211a) {
378 hostapd_hw_mode = kHostapdHwMode80211a;
379 } else if (hw_mode == kHwMode80211b) {
380 hostapd_hw_mode = kHostapdHwMode80211b;
381 } else if (hw_mode == kHwMode80211g) {
382 hostapd_hw_mode = kHostapdHwMode80211g;
383 } else if (hw_mode == kHwMode80211n) {
384 // Use 802.11a for 5GHz channel and 802.11g for 2.4GHz channel
385 if (GetChannel() >= 34) {
386 hostapd_hw_mode = kHostapdHwMode80211a;
387 } else {
388 hostapd_hw_mode = kHostapdHwMode80211g;
389 }
390 base::StringAppendF(config_str, "%s=1\n", kHostapdConfigKeyIeee80211n);
391
392 // Get HT Capability.
393 string ht_cap;
394 if (!device_->GetHTCapability(GetChannel(), &ht_cap)) {
395 Error::PopulateAndLog(error,
396 Error::kInvalidConfiguration,
397 "Failed to get HT Capability",
398 FROM_HERE);
399 return false;
400 }
401 base::StringAppendF(config_str, "%s=%s\n",
402 kHostapdConfigKeyHTCapability,
403 ht_cap.c_str());
404 } else if (hw_mode == kHwMode80211ac) {
405 if (GetChannel() >= 34) {
406 hostapd_hw_mode = kHostapdHwMode80211a;
407 } else {
408 hostapd_hw_mode = kHostapdHwMode80211g;
409 }
410 base::StringAppendF(config_str, "%s=1\n", kHostapdConfigKeyIeee80211ac);
411
412 // TODO(zqiu): Determine VHT Capabilities based on the interface PHY's
413 // capababilites.
414 } else {
415 Error::PopulateAndLog(
416 error,
417 Error::kInvalidConfiguration,
418 base::StringPrintf("Invalid hardware mode: %s", hw_mode.c_str()),
419 FROM_HERE);
420 return false;
421 }
422
423 base::StringAppendF(
424 config_str, "%s=%s\n", kHostapdConfigKeyHwMode, hostapd_hw_mode.c_str());
425 return true;
426 }
427
AppendHostapdDefaults(Error * error,string * config_str)428 bool Config::AppendHostapdDefaults(Error* error, string* config_str) {
429 // Driver: NL80211.
430 base::StringAppendF(
431 config_str, "%s=%s\n", kHostapdConfigKeyDriver, kHostapdDefaultDriver);
432
433 // Fragmentation threshold: disabled.
434 base::StringAppendF(config_str,
435 "%s=%d\n",
436 kHostapdConfigKeyFragmThreshold,
437 kHostapdDefaultFragmThreshold);
438
439 // RTS threshold: disabled.
440 base::StringAppendF(config_str,
441 "%s=%d\n",
442 kHostapdConfigKeyRtsThreshold,
443 kHostapdDefaultRtsThreshold);
444
445 return true;
446 }
447
AppendInterface(Error * error,string * config_str)448 bool Config::AppendInterface(Error* error, string* config_str) {
449 string interface = GetInterfaceName();
450 if (interface.empty()) {
451 // Ask manager for unused ap capable device.
452 device_ = manager_->GetAvailableDevice();
453 if (!device_) {
454 Error::PopulateAndLog(
455 error, Error::kInternalError, "No device available", FROM_HERE);
456 return false;
457 }
458 } else {
459 device_ = manager_->GetDeviceFromInterfaceName(interface);
460 if (!device_) {
461 Error::PopulateAndLog(
462 error,
463 Error::kInvalidConfiguration,
464 base::StringPrintf(
465 "Unable to find device for the specified interface [%s]",
466 interface.c_str()),
467 FROM_HERE);
468 return false;
469 }
470 if (device_->GetInUse()) {
471 Error::PopulateAndLog(
472 error,
473 Error::kInvalidConfiguration,
474 base::StringPrintf("Device [%s] for interface [%s] already in use",
475 device_->GetDeviceName().c_str(),
476 interface.c_str()),
477 FROM_HERE);
478 return false;
479 }
480 }
481
482 // Use the preferred AP interface from the device.
483 selected_interface_ = device_->GetPreferredApInterface();
484 base::StringAppendF(config_str,
485 "%s=%s\n",
486 kHostapdConfigKeyInterface,
487 selected_interface_.c_str());
488 return true;
489 }
490
AppendSecurityMode(Error * error,string * config_str)491 bool Config::AppendSecurityMode(Error* error, string* config_str) {
492 string security_mode = GetSecurityMode();
493 if (security_mode == kSecurityModeNone) {
494 // Nothing need to be done for open network.
495 return true;
496 }
497
498 if (security_mode == kSecurityModeRSN) {
499 string passphrase = GetPassphrase();
500 if (passphrase.empty()) {
501 Error::PopulateAndLog(
502 error,
503 Error::kInvalidConfiguration,
504 base::StringPrintf("Passphrase not set for security mode: %s",
505 security_mode.c_str()),
506 FROM_HERE);
507 return false;
508 }
509
510 base::StringAppendF(config_str, "%s=2\n", kHostapdConfigKeyWpa);
511 base::StringAppendF(config_str,
512 "%s=%s\n",
513 kHostapdConfigKeyRsnPairwise,
514 kHostapdDefaultRsnPairwise);
515 base::StringAppendF(config_str,
516 "%s=%s\n",
517 kHostapdConfigKeyWpaKeyMgmt,
518 kHostapdDefaultWpaKeyMgmt);
519 base::StringAppendF(config_str,
520 "%s=%s\n",
521 kHostapdConfigKeyWpaPassphrase,
522 passphrase.c_str());
523 return true;
524 }
525
526 Error::PopulateAndLog(
527 error,
528 Error::kInvalidConfiguration,
529 base::StringPrintf("Invalid security mode: %s", security_mode.c_str()),
530 FROM_HERE);
531 return false;
532 }
533
534 } // namespace apmanager
535