blob: 7dc91797c8a47a7c56bd7a7fe6319996d99d505d [file] [log] [blame]
mukesh agrawal4d0401c2012-01-06 16:05:31 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
mukesh agrawal6e277772011-09-29 15:04:23 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/wpa_supplicant.h"
6
Paul Stewart0654ece2013-03-26 15:21:26 -07007#include <map>
8#include <string>
9#include <vector>
10
11#include <base/file_path.h>
12
13#include "shill/certificate_file.h"
14#include "shill/eap_credentials.h"
15#include "shill/nss.h"
16
17using base::FilePath;
18using std::map;
19using std::string;
20using std::vector;
21
mukesh agrawal6e277772011-09-29 15:04:23 -070022namespace shill {
23
Paul Stewart0654ece2013-03-26 15:21:26 -070024// static
25const char WPASupplicant::kBSSPropertyBSSID[] = "BSSID";
26const char WPASupplicant::kBSSPropertyFrequency[] = "Frequency";
27const char WPASupplicant::kBSSPropertyIEs[] = "IEs";
28const char WPASupplicant::kBSSPropertyMode[] = "Mode";
29const char WPASupplicant::kBSSPropertyRates[] = "Rates";
30const char WPASupplicant::kBSSPropertySSID[] = "SSID";
31const char WPASupplicant::kBSSPropertySignal[] = "Signal";
Gaurav Shah10109f22011-11-11 20:16:22 -080032// TODO(gauravsh): Make this path be a configurable option. crosbug.com/25661
33// Location of the system root CA certificates.
Paul Stewart0654ece2013-03-26 15:21:26 -070034const char WPASupplicant::kCaPath[] = "/etc/ssl/certs";
35const char WPASupplicant::kCurrentBSSNull[] = "/";
36const char WPASupplicant::kDBusAddr[] = "fi.w1.wpa_supplicant1";
37const char WPASupplicant::kDBusPath[] = "/fi/w1/wpa_supplicant1";
38const char WPASupplicant::kDebugLevelDebug[] = "debug";
39const char WPASupplicant::kDebugLevelError[] = "error";
40const char WPASupplicant::kDebugLevelExcessive[] = "excessive";
41const char WPASupplicant::kDebugLevelInfo[] = "info";
42const char WPASupplicant::kDebugLevelMsgDump[] = "msgdump";
43const char WPASupplicant::kDebugLevelWarning[] = "warning";
44const char WPASupplicant::kDriverNL80211[] = "nl80211";
Paul Stewart196f50f2013-03-27 18:02:11 -070045const char WPASupplicant::kDriverWired[] = "wired";
Paul Stewart0654ece2013-03-26 15:21:26 -070046const char WPASupplicant::kEAPParameterAlertUnknownCA[] = "unknown CA";
47const char WPASupplicant::kEAPParameterFailure[] = "failure";
48const char WPASupplicant::kEAPParameterSuccess[] = "success";
49const char WPASupplicant::kEAPStatusAcceptProposedMethod[] =
50 "accept proposed method";
51const char WPASupplicant::kEAPStatusCompletion[] = "completion";
52const char WPASupplicant::kEAPStatusLocalTLSAlert[] = "local TLS alert";
53const char WPASupplicant::kEAPStatusParameterNeeded[] = "eap parameter needed";
54const char WPASupplicant::kEAPStatusRemoteCertificateVerification[] =
Paul Stewartdb0f9172012-11-30 16:48:09 -080055 "remote certificate verification";
Paul Stewart0654ece2013-03-26 15:21:26 -070056const char WPASupplicant::kEAPStatusRemoteTLSAlert[] = "remote TLS alert";
57const char WPASupplicant::kEAPStatusStarted[] = "started";
58const char WPASupplicant::kEnginePKCS11[] = "pkcs11";
59const char WPASupplicant::kErrorNetworkUnknown[]
60 = "fi.w1.wpa_supplicant1.NetworkUnknown";
61const char WPASupplicant::kErrorInterfaceExists[]
62 = "fi.w1.wpa_supplicant1.InterfaceExists";
63const char WPASupplicant::kInterfacePropertyConfigFile[] = "ConfigFile";
64const char WPASupplicant::kInterfacePropertyCurrentBSS[] = "CurrentBSS";
65const char WPASupplicant::kInterfacePropertyDepth[] = "depth";
66const char WPASupplicant::kInterfacePropertyDriver[] = "Driver";
67const char WPASupplicant::kInterfacePropertyName[] = "Ifname";
68const char WPASupplicant::kInterfacePropertyState[] = "State";
69const char WPASupplicant::kInterfacePropertySubject[] = "subject";
70const char WPASupplicant::kInterfaceState4WayHandshake[] = "4way_handshake";
71const char WPASupplicant::kInterfaceStateAssociated[] = "associated";
72const char WPASupplicant::kInterfaceStateAssociating[] = "associating";
73const char WPASupplicant::kInterfaceStateAuthenticating[] = "authenticating";
74const char WPASupplicant::kInterfaceStateCompleted[] = "completed";
75const char WPASupplicant::kInterfaceStateDisconnected[] = "disconnected";
76const char WPASupplicant::kInterfaceStateGroupHandshake[] = "group_handshake";
77const char WPASupplicant::kInterfaceStateInactive[] = "inactive";
78const char WPASupplicant::kInterfaceStateScanning[] = "scanning";
79const char WPASupplicant::kKeyManagementMethodSuffixEAP[] = "-eap";
80const char WPASupplicant::kKeyManagementMethodSuffixPSK[] = "-psk";
81const char WPASupplicant::kKeyModeNone[] = "NONE";
82const char WPASupplicant::kNetworkBgscanMethodLearn[] = "learn";
Christopher Wileya998df22012-07-11 15:14:55 -070083// None is not a real method name, but we interpret 'none' as a request that
84// no background scan parameter should be supplied to wpa_supplicant.
Paul Stewart0654ece2013-03-26 15:21:26 -070085const char WPASupplicant::kNetworkBgscanMethodNone[] = "none";
86const char WPASupplicant::kNetworkBgscanMethodSimple[] = "simple";
87const char WPASupplicant::kNetworkModeInfrastructure[] = "infrastructure";
88const char WPASupplicant::kNetworkModeAdHoc[] = "ad-hoc";
89const char WPASupplicant::kNetworkModeAccessPoint[] = "ap";
90const char WPASupplicant::kNetworkPropertyBgscan[] = "bgscan";
91const char WPASupplicant::kNetworkPropertyCaPath[] = "ca_path";
92const char WPASupplicant::kNetworkPropertyEapIdentity[] = "identity";
93const char WPASupplicant::kNetworkPropertyEapKeyManagement[] = "key_mgmt";
94const char WPASupplicant::kNetworkPropertyEapEap[] = "eap";
95const char WPASupplicant::kNetworkPropertyEapInnerEap[] = "phase2";
96const char WPASupplicant::kNetworkPropertyEapAnonymousIdentity[]
97 = "anonymous_identity";
98const char WPASupplicant::kNetworkPropertyEapClientCert[] = "client_cert";
99const char WPASupplicant::kNetworkPropertyEapPrivateKey[] = "private_key";
100const char WPASupplicant::kNetworkPropertyEapPrivateKeyPassword[] =
101 "private_key_passwd";
102const char WPASupplicant::kNetworkPropertyEapCaCert[] = "ca_cert";
103const char WPASupplicant::kNetworkPropertyEapCaPassword[] = "password";
104const char WPASupplicant::kNetworkPropertyEapCertId[] = "cert_id";
105const char WPASupplicant::kNetworkPropertyEapKeyId[] = "key_id";
106const char WPASupplicant::kNetworkPropertyEapCaCertId[] = "ca_cert_id";
107const char WPASupplicant::kNetworkPropertyEapPin[] = "pin";
108const char WPASupplicant::kNetworkPropertyEapSubjectMatch[] = "subject_match";
109const char WPASupplicant::kNetworkPropertyEngine[] = "engine";
110const char WPASupplicant::kNetworkPropertyEngineId[] = "engine_id";
111const char WPASupplicant::kNetworkPropertyFrequency[] = "frequency";
112const char WPASupplicant::kNetworkPropertyIeee80211w[] = "ieee80211w";
113const char WPASupplicant::kNetworkPropertyMode[] = "mode";
114const char WPASupplicant::kNetworkPropertyScanSSID[] = "scan_ssid";
115const char WPASupplicant::kNetworkPropertySSID[] = "ssid";
116const char WPASupplicant::kPropertyAuthAlg[] = "auth_alg";
117const char WPASupplicant::kPropertyPreSharedKey[] = "psk";
118const char WPASupplicant::kPropertyPrivacy[] = "Privacy";
119const char WPASupplicant::kPropertyRSN[] = "RSN";
120const char WPASupplicant::kPropertyScanSSIDs[] = "SSIDs";
121const char WPASupplicant::kPropertyScanType[] = "Type";
122const char WPASupplicant::kPropertySecurityProtocol[] = "proto";
123const char WPASupplicant::kPropertyWEPKey[] = "wep_key";
124const char WPASupplicant::kPropertyWEPTxKeyIndex[] = "wep_tx_keyidx";
125const char WPASupplicant::kPropertyWPA[] = "WPA";
126const char WPASupplicant::kScanTypeActive[] = "active";
127const char WPASupplicant::kSecurityAuthAlg[] = "OPEN SHARED";
128const char WPASupplicant::kSecurityMethodPropertyKeyManagement[] = "KeyMgmt";
129const char WPASupplicant::kSecurityModeRSN[] = "RSN";
130const char WPASupplicant::kSecurityModeWPA[] = "WPA";
mukesh agrawal6e277772011-09-29 15:04:23 -0700131
Paul Stewart0654ece2013-03-26 15:21:26 -0700132const uint32_t WPASupplicant::kDefaultEngine = 1;
133const uint32_t WPASupplicant::kNetworkIeee80211wDisabled = 0;
134const uint32_t WPASupplicant::kNetworkIeee80211wEnabled = 1;
135const uint32_t WPASupplicant::kNetworkIeee80211wRequired = 2;
136const uint32_t WPASupplicant::kNetworkModeInfrastructureInt = 0;
137const uint32_t WPASupplicant::kNetworkModeAdHocInt = 1;
138const uint32_t WPASupplicant::kNetworkModeAccessPointInt = 2;
139const uint32_t WPASupplicant::kScanMaxSSIDsPerScan = 4;
140
Paul Stewart196f50f2013-03-27 18:02:11 -0700141const char WPASupplicant::kSupplicantConfPath[] =
142 SHIMDIR "/wpa_supplicant.conf";
143
Paul Stewart0654ece2013-03-26 15:21:26 -0700144// static
145void WPASupplicant::Populate8021xProperties(
146 const EapCredentials &eap, CertificateFile *certificate_file,
147 NSS *nss, const vector<char> nss_identifier,
148 map<string, DBus::Variant> *params) {
149 string ca_cert = eap.ca_cert;
150 if (!eap.ca_cert_pem.empty()) {
151 FilePath certfile =
152 certificate_file->CreateDERFromString(eap.ca_cert_pem);
153 if (certfile.empty()) {
154 LOG(ERROR) << "Unable to extract PEM certificate.";
155 } else {
156 ca_cert = certfile.value();
157 }
158 } else if (!eap.ca_cert_nss.empty()) {
159 FilePath certfile = nss->GetDERCertfile(eap.ca_cert_nss, nss_identifier);
160 if (certfile.empty()) {
161 LOG(ERROR) << "Unable to extract DER certificate: " << eap.ca_cert_nss;
162 } else {
163 ca_cert = certfile.value();
164 }
165 }
166
167
168 typedef std::pair<const char *, const char *> KeyVal;
169 KeyVal init_propertyvals[] = {
170 KeyVal(WPASupplicant::kNetworkPropertyEapIdentity, eap.identity.c_str()),
171 KeyVal(WPASupplicant::kNetworkPropertyEapEap, eap.eap.c_str()),
172 KeyVal(WPASupplicant::kNetworkPropertyEapInnerEap,
173 eap.inner_eap.c_str()),
174 KeyVal(WPASupplicant::kNetworkPropertyEapAnonymousIdentity,
175 eap.anonymous_identity.c_str()),
176 KeyVal(WPASupplicant::kNetworkPropertyEapClientCert,
177 eap.client_cert.c_str()),
178 KeyVal(WPASupplicant::kNetworkPropertyEapPrivateKey,
179 eap.private_key.c_str()),
180 KeyVal(WPASupplicant::kNetworkPropertyEapPrivateKeyPassword,
181 eap.private_key_password.c_str()),
182 KeyVal(WPASupplicant::kNetworkPropertyEapCaCert, ca_cert.c_str()),
183 KeyVal(WPASupplicant::kNetworkPropertyEapCaPassword,
184 eap.password.c_str()),
185 KeyVal(WPASupplicant::kNetworkPropertyEapCertId, eap.cert_id.c_str()),
186 KeyVal(WPASupplicant::kNetworkPropertyEapKeyId, eap.key_id.c_str()),
187 KeyVal(WPASupplicant::kNetworkPropertyEapCaCertId,
188 eap.ca_cert_id.c_str()),
189 KeyVal(WPASupplicant::kNetworkPropertyEapSubjectMatch,
190 eap.subject_match.c_str())
191 };
192
193 vector<KeyVal> propertyvals(init_propertyvals,
194 init_propertyvals + arraysize(init_propertyvals));
195 if (eap.use_system_cas) {
196 propertyvals.push_back(KeyVal(
197 WPASupplicant::kNetworkPropertyCaPath, WPASupplicant::kCaPath));
198 } else if (ca_cert.empty()) {
199 LOG(WARNING) << __func__
200 << ": No certificate authorities are configured."
201 << " Server certificates will be accepted"
202 << " unconditionally.";
203 }
204
205 if (!eap.cert_id.empty() || !eap.key_id.empty() ||
206 !eap.ca_cert_id.empty()) {
207 propertyvals.push_back(KeyVal(
208 WPASupplicant::kNetworkPropertyEapPin, eap.pin.c_str()));
209 propertyvals.push_back(KeyVal(
210 WPASupplicant::kNetworkPropertyEngineId,
211 WPASupplicant::kEnginePKCS11));
212 // We can't use the propertyvals vector for this since this argument
213 // is a uint32, not a string.
214 (*params)[WPASupplicant::kNetworkPropertyEngine].writer().
215 append_uint32(WPASupplicant::kDefaultEngine);
216 }
217
218 vector<KeyVal>::iterator it;
219 for (it = propertyvals.begin(); it != propertyvals.end(); ++it) {
220 if (strlen((*it).second) > 0) {
221 (*params)[(*it).first].writer().append_string((*it).second);
222 }
223 }
224}
mukesh agrawal6e277772011-09-29 15:04:23 -0700225
Paul Stewart735eab52013-03-29 09:19:23 -0700226// static
227bool WPASupplicant::ExtractRemoteCertification(
228 const std::map<std::string, DBus::Variant> &properties,
229 std::string *subject, uint32 *depth) {
230 map<string, ::DBus::Variant>::const_iterator depth_it =
231 properties.find(WPASupplicant::kInterfacePropertyDepth);
232 if (depth_it == properties.end()) {
233 LOG(ERROR) << __func__ << " no depth parameter.";
234 return false;
235 }
236 map<string, ::DBus::Variant>::const_iterator subject_it =
237 properties.find(WPASupplicant::kInterfacePropertySubject);
238 if (subject_it == properties.end()) {
239 LOG(ERROR) << __func__ << " no subject parameter.";
240 return false;
241 }
242 *depth = depth_it->second.reader().get_uint32();
243 *subject = subject_it->second.reader().get_string();
244 return true;
245}
246
mukesh agrawal6e277772011-09-29 15:04:23 -0700247} // namespace shill