OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/cros/onc_network_parser.h" | 5 #include "chrome/browser/chromeos/cros/onc_network_parser.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/json/json_value_serializer.h" | 8 #include "base/json/json_value_serializer.h" |
9 #include "base/json/json_writer.h" // for debug output only. | |
10 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
11 #include "base/values.h" | 10 #include "base/values.h" |
12 #include "chrome/browser/chromeos/cros/native_network_constants.h" | 11 #include "chrome/browser/chromeos/cros/native_network_constants.h" |
13 #include "chrome/browser/chromeos/cros/native_network_parser.h" | 12 #include "chrome/browser/chromeos/cros/native_network_parser.h" |
14 #include "chrome/browser/chromeos/cros/network_library.h" | 13 #include "chrome/browser/chromeos/cros/network_library.h" |
15 #include "net/base/cert_database.h" | 14 #include "net/base/cert_database.h" |
16 #include "net/base/crypto_module.h" | 15 #include "net/base/crypto_module.h" |
17 #include "net/base/net_errors.h" | 16 #include "net/base/net_errors.h" |
18 #include "net/base/x509_certificate.h" | 17 #include "net/base/x509_certificate.h" |
19 #include "third_party/cros_system_api/dbus/service_constants.h" | 18 #include "third_party/cros_system_api/dbus/service_constants.h" |
20 | 19 |
21 namespace chromeos { | 20 namespace chromeos { |
22 | 21 |
23 // Local constants. | 22 // Local constants. |
24 namespace { | 23 namespace { |
25 | 24 |
26 const base::Value::Type TYPE_BOOLEAN = base::Value::TYPE_BOOLEAN; | 25 EnumMapper<PropertyIndex>::Pair property_index_table[] = { |
27 const base::Value::Type TYPE_DICTIONARY = base::Value::TYPE_DICTIONARY; | 26 { "GUID", PROPERTY_INDEX_GUID }, |
28 const base::Value::Type TYPE_INTEGER = base::Value::TYPE_INTEGER; | 27 { "Name", PROPERTY_INDEX_NAME }, |
29 const base::Value::Type TYPE_LIST = base::Value::TYPE_LIST; | 28 { "Remove", PROPERTY_INDEX_REMOVE }, |
30 const base::Value::Type TYPE_STRING = base::Value::TYPE_STRING; | 29 { "ProxyURL", PROPERTY_INDEX_PROXY_CONFIG }, |
31 | 30 { "Type", PROPERTY_INDEX_TYPE }, |
32 // Only used currently to keep NetworkParser superclass happy. | 31 { "SSID", PROPERTY_INDEX_SSID }, |
33 EnumMapper<PropertyIndex>::Pair network_configuration_table[] = { | 32 { "Passphrase", PROPERTY_INDEX_PASSPHRASE }, |
34 { "GUID", PROPERTY_INDEX_GUID } | 33 { "AutoConnect", PROPERTY_INDEX_AUTO_CONNECT }, |
35 }; | 34 { "HiddenSSID", PROPERTY_INDEX_HIDDEN_SSID }, |
36 | 35 { "Security", PROPERTY_INDEX_SECURITY }, |
37 OncValueSignature network_configuration_signature[] = { | 36 { "EAP", PROPERTY_INDEX_EAP }, |
38 // TODO(crosbug.com/23673): Support Ethernet settings. | 37 { "Outer", PROPERTY_INDEX_EAP_METHOD }, |
39 { "GUID", PROPERTY_INDEX_GUID, TYPE_STRING }, | 38 { "Inner", PROPERTY_INDEX_EAP_PHASE_2_AUTH }, |
40 { "Name", PROPERTY_INDEX_NAME, TYPE_STRING }, | 39 { "UseSystemCAs", PROPERTY_INDEX_EAP_USE_SYSTEM_CAS }, |
41 // TODO(crosbug.com/23674): Support ProxySettings. | 40 { "ServerCARef", PROPERTY_INDEX_EAP_CA_CERT }, |
42 // TODO(crosbug.com/23604): Handle removing networks. | 41 { "ClientCARef", PROPERTY_INDEX_EAP_CLIENT_CERT }, |
43 { "Remove", PROPERTY_INDEX_ONC_REMOVE, TYPE_BOOLEAN }, | 42 { "ClientCertPattern", PROPERTY_INDEX_EAP_CLIENT_CERT_PATTERN }, |
44 { "Type", PROPERTY_INDEX_TYPE, TYPE_STRING }, | 43 { "Identity", PROPERTY_INDEX_EAP_IDENTITY }, |
45 { "WiFi", PROPERTY_INDEX_ONC_WIFI, TYPE_DICTIONARY }, | 44 { "Password", PROPERTY_INDEX_EAP_PASSWORD }, |
46 { "VPN", PROPERTY_INDEX_ONC_VPN, TYPE_DICTIONARY } | 45 { "AnonymousIdentity", PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY }, |
47 }; | |
48 | |
49 OncValueSignature wifi_signature[] = { | |
50 { "AutoConnect", PROPERTY_INDEX_AUTO_CONNECT, TYPE_BOOLEAN }, | |
51 { "EAP", PROPERTY_INDEX_EAP, TYPE_DICTIONARY }, | |
52 { "HiddenSSID", PROPERTY_INDEX_HIDDEN_SSID, TYPE_BOOLEAN }, | |
53 { "Passphrase", PROPERTY_INDEX_PASSPHRASE, TYPE_STRING }, | |
54 { "ProxyURL", PROPERTY_INDEX_PROXY_CONFIG, TYPE_STRING }, | |
55 { "Security", PROPERTY_INDEX_SECURITY, TYPE_STRING }, | |
56 { "SSID", PROPERTY_INDEX_SSID, TYPE_STRING }, | |
57 { NULL } | |
58 }; | |
59 | |
60 OncValueSignature eap_signature[] = { | |
61 { "AnonymousIdentity", PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY, TYPE_STRING }, | |
62 { "ClientCertPattern", PROPERTY_INDEX_ONC_CLIENT_CERT_PATTERN, | |
63 TYPE_DICTIONARY }, | |
64 { "ClientCertRef", PROPERTY_INDEX_ONC_CLIENT_CERT_REF, TYPE_STRING }, | |
65 { "ClientCertType", PROPERTY_INDEX_ONC_CLIENT_CERT_TYPE, TYPE_STRING }, | |
66 { "Identity", PROPERTY_INDEX_EAP_IDENTITY, TYPE_STRING }, | |
67 { "Inner", PROPERTY_INDEX_EAP_PHASE_2_AUTH, TYPE_STRING }, | |
68 { "Outer", PROPERTY_INDEX_EAP_METHOD, TYPE_STRING }, | |
69 { "Password", PROPERTY_INDEX_EAP_PASSWORD, TYPE_STRING }, | |
70 { "ServerCARef", PROPERTY_INDEX_EAP_CA_CERT, TYPE_STRING }, | |
71 { "UseSystemCAs", PROPERTY_INDEX_EAP_USE_SYSTEM_CAS, TYPE_BOOLEAN }, | |
72 { NULL } | |
73 }; | |
74 | |
75 OncValueSignature vpn_signature[] = { | |
76 { "Host", PROPERTY_INDEX_PROVIDER_HOST, TYPE_STRING }, | |
77 { "IPsec", PROPERTY_INDEX_ONC_IPSEC, TYPE_DICTIONARY }, | |
78 { "L2TP", PROPERTY_INDEX_ONC_L2TP, TYPE_DICTIONARY }, | |
79 { "OpenVPN", PROPERTY_INDEX_ONC_OPENVPN, TYPE_DICTIONARY }, | |
80 { "Type", PROPERTY_INDEX_PROVIDER_TYPE, TYPE_STRING }, | |
81 { NULL } | |
82 }; | |
83 | |
84 OncValueSignature ipsec_signature[] = { | |
85 { "AuthenticationType", PROPERTY_INDEX_IPSEC_AUTHENTICATIONTYPE, | |
86 TYPE_STRING }, | |
87 { "Group", PROPERTY_INDEX_L2TPIPSEC_GROUP_NAME, TYPE_STRING }, | |
88 { "IKEVersion", PROPERTY_INDEX_IPSEC_IKEVERSION, TYPE_INTEGER }, | |
89 { "ClientCertPattern", PROPERTY_INDEX_ONC_CLIENT_CERT_PATTERN, | |
90 TYPE_DICTIONARY }, | |
91 { "ClientCertRef", PROPERTY_INDEX_ONC_CLIENT_CERT_REF, TYPE_STRING }, | |
92 { "ClientCertType", PROPERTY_INDEX_ONC_CLIENT_CERT_TYPE, TYPE_STRING }, | |
93 // Note: EAP and XAUTH not yet supported. | |
94 { "PSK", PROPERTY_INDEX_L2TPIPSEC_PSK, TYPE_STRING }, | |
95 { "SaveCredentials", PROPERTY_INDEX_SAVE_CREDENTIALS, TYPE_BOOLEAN }, | |
96 { "ServerCARef", PROPERTY_INDEX_L2TPIPSEC_CA_CERT_NSS, TYPE_STRING }, | |
97 { NULL } | |
98 }; | |
99 | |
100 OncValueSignature l2tp_signature[] = { | |
101 { "Password", PROPERTY_INDEX_L2TPIPSEC_PASSWORD, TYPE_STRING }, | |
102 { "SaveCredentials", PROPERTY_INDEX_SAVE_CREDENTIALS, TYPE_BOOLEAN }, | |
103 { "Username", PROPERTY_INDEX_L2TPIPSEC_USER, TYPE_STRING }, | |
104 { NULL } | |
105 }; | |
106 | |
107 OncValueSignature openvpn_signature[] = { | |
108 { "Auth", PROPERTY_INDEX_OPEN_VPN_AUTH, TYPE_STRING }, | |
109 { "AuthRetry", PROPERTY_INDEX_OPEN_VPN_AUTHRETRY, TYPE_STRING }, | |
110 { "AuthNoCache", PROPERTY_INDEX_OPEN_VPN_AUTHNOCACHE, TYPE_BOOLEAN }, | |
111 { "Cipher", PROPERTY_INDEX_OPEN_VPN_CIPHER, TYPE_STRING }, | |
112 { "ClientCertPattern", PROPERTY_INDEX_ONC_CLIENT_CERT_PATTERN, | |
113 TYPE_DICTIONARY }, | |
114 { "ClientCertRef", PROPERTY_INDEX_ONC_CLIENT_CERT_REF, TYPE_STRING }, | |
115 { "ClientCertType", PROPERTY_INDEX_ONC_CLIENT_CERT_TYPE, TYPE_STRING }, | |
116 { "CompLZO", PROPERTY_INDEX_OPEN_VPN_COMPLZO, TYPE_STRING }, | |
117 { "CompNoAdapt", PROPERTY_INDEX_OPEN_VPN_COMPNOADAPT, TYPE_BOOLEAN }, | |
118 { "KeyDirection", PROPERTY_INDEX_OPEN_VPN_KEYDIRECTION, TYPE_STRING }, | |
119 { "NsCertType", PROPERTY_INDEX_OPEN_VPN_NSCERTTYPE, TYPE_STRING }, | |
120 { "Password", PROPERTY_INDEX_OPEN_VPN_PASSWORD, TYPE_STRING }, | |
121 { "Port", PROPERTY_INDEX_OPEN_VPN_PORT, TYPE_INTEGER }, | |
122 { "Proto", PROPERTY_INDEX_OPEN_VPN_PROTO, TYPE_STRING }, | |
123 { "PushPeerInfo", PROPERTY_INDEX_OPEN_VPN_PUSHPEERINFO, TYPE_BOOLEAN }, | |
124 { "RemoteCertEKU", PROPERTY_INDEX_OPEN_VPN_REMOTECERTEKU, TYPE_STRING }, | |
125 { "RemoteCertKU", PROPERTY_INDEX_OPEN_VPN_REMOTECERTKU, TYPE_LIST }, | |
126 { "RemoteCertTLS", PROPERTY_INDEX_OPEN_VPN_REMOTECERTTLS, TYPE_STRING }, | |
127 { "RenegSec", PROPERTY_INDEX_OPEN_VPN_RENEGSEC, TYPE_INTEGER }, | |
128 { "SaveCredentials", PROPERTY_INDEX_SAVE_CREDENTIALS, TYPE_BOOLEAN }, | |
129 { "ServerCARef", PROPERTY_INDEX_OPEN_VPN_CACERT, TYPE_STRING }, | |
130 { "ServerCertRef", PROPERTY_INDEX_OPEN_VPN_CERT, TYPE_STRING }, | |
131 { "ServerPollTimeout", PROPERTY_INDEX_OPEN_VPN_SERVERPOLLTIMEOUT, | |
132 TYPE_INTEGER }, | |
133 { "Shaper", PROPERTY_INDEX_OPEN_VPN_SHAPER, TYPE_INTEGER }, | |
134 { "StaticChallenge", PROPERTY_INDEX_OPEN_VPN_STATICCHALLENGE, TYPE_STRING }, | |
135 { "TLSAuthContents", PROPERTY_INDEX_OPEN_VPN_TLSAUTHCONTENTS, TYPE_STRING }, | |
136 { "TLSRemote", PROPERTY_INDEX_OPEN_VPN_TLSREMOTE, TYPE_STRING }, | |
137 { "Username", PROPERTY_INDEX_OPEN_VPN_USER, TYPE_STRING }, | |
138 { NULL } | |
139 }; | 46 }; |
140 | 47 |
141 // Serve the singleton mapper instance. | 48 // Serve the singleton mapper instance. |
142 const EnumMapper<PropertyIndex>* get_onc_mapper() { | 49 const EnumMapper<PropertyIndex>* get_onc_mapper() { |
143 CR_DEFINE_STATIC_LOCAL(const EnumMapper<PropertyIndex>, mapper, | 50 CR_DEFINE_STATIC_LOCAL(const EnumMapper<PropertyIndex>, mapper, |
144 (network_configuration_table, | 51 (property_index_table, |
145 arraysize(network_configuration_table), | 52 arraysize(property_index_table), |
146 PROPERTY_INDEX_UNKNOWN)); | 53 PROPERTY_INDEX_UNKNOWN)); |
147 return &mapper; | 54 return &mapper; |
148 } | 55 } |
149 | 56 |
150 ConnectionType ParseNetworkType(const std::string& type) { | 57 ConnectionType ParseNetworkType(const std::string& type) { |
151 static EnumMapper<ConnectionType>::Pair table[] = { | 58 static EnumMapper<ConnectionType>::Pair table[] = { |
152 { "WiFi", TYPE_WIFI }, | 59 { "WiFi", TYPE_WIFI }, |
153 { "VPN", TYPE_VPN }, | 60 { "VPN", TYPE_VPN }, |
154 }; | 61 }; |
155 CR_DEFINE_STATIC_LOCAL(EnumMapper<ConnectionType>, parser, | 62 CR_DEFINE_STATIC_LOCAL(EnumMapper<ConnectionType>, parser, |
156 (table, arraysize(table), TYPE_UNKNOWN)); | 63 (table, arraysize(table), TYPE_UNKNOWN)); |
157 return parser.Get(type); | 64 return parser.Get(type); |
158 } | 65 } |
159 | 66 |
160 std::string GetStringValue(const base::Value& value) { | |
161 std::string string_value; | |
162 value.GetAsString(&string_value); | |
163 return string_value; | |
164 } | |
165 | |
166 const bool GetBooleanValue(const base::Value& value) { | |
167 bool bool_value = false; | |
168 value.GetAsBoolean(&bool_value); | |
169 return bool_value; | |
170 } | |
171 | |
172 std::string ConvertValueToString(const base::Value& value) { | |
173 std::string value_json; | |
174 base::JSONWriter::Write(&value, false, &value_json); | |
175 return value_json; | |
176 } | |
177 | |
178 } // namespace | 67 } // namespace |
179 | 68 |
180 // -------------------- OncNetworkParser -------------------- | 69 // -------------------- OncNetworkParser -------------------- |
181 | 70 |
182 OncNetworkParser::OncNetworkParser(const std::string& onc_blob) | 71 OncNetworkParser::OncNetworkParser(const std::string& onc_blob) |
183 : NetworkParser(get_onc_mapper()), | 72 : NetworkParser(get_onc_mapper()), |
184 network_configs_(NULL), | 73 network_configs_(NULL), |
185 certificates_(NULL) { | 74 certificates_(NULL) { |
186 VLOG(2) << __func__ << ": OncNetworkParser called on " << onc_blob; | |
187 JSONStringValueSerializer deserializer(onc_blob); | 75 JSONStringValueSerializer deserializer(onc_blob); |
188 deserializer.set_allow_trailing_comma(true); | 76 deserializer.set_allow_trailing_comma(true); |
189 scoped_ptr<base::Value> root(deserializer.Deserialize(NULL, &parse_error_)); | 77 scoped_ptr<base::Value> root(deserializer.Deserialize(NULL, &parse_error_)); |
190 | 78 |
191 if (!root.get() || root->GetType() != base::Value::TYPE_DICTIONARY) { | 79 if (!root.get() || root->GetType() != base::Value::TYPE_DICTIONARY) { |
192 LOG(WARNING) << "OncNetworkParser received bad ONC file: " << parse_error_; | 80 LOG(WARNING) << "OncNetworkParser received bad ONC file: " << parse_error_; |
193 } else { | 81 } else { |
194 root_dict_.reset(static_cast<DictionaryValue*>(root.release())); | 82 root_dict_.reset(static_cast<DictionaryValue*>(root.release())); |
195 // At least one of NetworkConfigurations or Certificates is required. | 83 // At least one of NetworkConfigurations or Certificates is required. |
196 bool has_network_configurations = | 84 if (!root_dict_->GetList("NetworkConfigurations", &network_configs_) && |
197 root_dict_->GetList("NetworkConfigurations", &network_configs_); | 85 !root_dict_->GetList("Certificates", &certificates_)) { |
198 bool has_certificates = | |
199 root_dict_->GetList("Certificates", &certificates_); | |
200 VLOG(2) << "ONC file has " << GetNetworkConfigsSize() << " networks and " | |
201 << GetCertificatesSize() << " certificates"; | |
202 if (!has_network_configurations || !has_certificates) { | |
203 LOG(WARNING) << "ONC file has no NetworkConfigurations or Certificates."; | 86 LOG(WARNING) << "ONC file has no NetworkConfigurations or Certificates."; |
204 } | 87 } |
205 } | 88 } |
206 } | 89 } |
207 | 90 |
208 OncNetworkParser::OncNetworkParser() | 91 OncNetworkParser::OncNetworkParser() |
209 : NetworkParser(get_onc_mapper()), | 92 : NetworkParser(get_onc_mapper()), |
210 network_configs_(NULL), | 93 network_configs_(NULL), |
211 certificates_(NULL) { | 94 certificates_(NULL) { |
212 } | 95 } |
(...skipping 15 matching lines...) Expand all Loading... |
228 } | 111 } |
229 | 112 |
230 bool OncNetworkParser::ParseCertificate(int cert_index) { | 113 bool OncNetworkParser::ParseCertificate(int cert_index) { |
231 CHECK(certificates_); | 114 CHECK(certificates_); |
232 CHECK(static_cast<size_t>(cert_index) < certificates_->GetSize()); | 115 CHECK(static_cast<size_t>(cert_index) < certificates_->GetSize()); |
233 CHECK(cert_index >= 0); | 116 CHECK(cert_index >= 0); |
234 base::DictionaryValue* certificate = NULL; | 117 base::DictionaryValue* certificate = NULL; |
235 certificates_->GetDictionary(cert_index, &certificate); | 118 certificates_->GetDictionary(cert_index, &certificate); |
236 CHECK(certificate); | 119 CHECK(certificate); |
237 | 120 |
238 if (VLOG_IS_ON(2)) { | |
239 std::string certificate_json; | |
240 base::JSONWriter::Write(static_cast<base::Value*>(certificate), | |
241 true, &certificate_json); | |
242 VLOG(2) << "Parsing certificate at index " << cert_index | |
243 << ": " << certificate_json; | |
244 } | |
245 | |
246 // Get out the attributes of the given cert. | 121 // Get out the attributes of the given cert. |
247 std::string guid; | 122 std::string guid; |
248 bool remove = false; | 123 bool remove = false; |
249 if (!certificate->GetString("GUID", &guid) || guid.empty()) { | 124 if (!certificate->GetString("GUID", &guid) || guid.empty()) { |
250 LOG(WARNING) << "ONC File: certificate missing identifier at index" | 125 LOG(WARNING) << "ONC File: certificate missing identifier at index" |
251 << cert_index; | 126 << cert_index; |
252 return false; | 127 return false; |
253 } | 128 } |
254 | 129 |
255 if (!certificate->GetBoolean("Remove", &remove)) | 130 if (!certificate->GetBoolean("Remove", &remove)) |
(...skipping 17 matching lines...) Expand all Loading... |
273 << " at index " << cert_index; | 148 << " at index " << cert_index; |
274 return false; | 149 return false; |
275 } | 150 } |
276 | 151 |
277 Network* OncNetworkParser::ParseNetwork(int n) { | 152 Network* OncNetworkParser::ParseNetwork(int n) { |
278 if (!network_configs_) | 153 if (!network_configs_) |
279 return NULL; | 154 return NULL; |
280 DictionaryValue* info = NULL; | 155 DictionaryValue* info = NULL; |
281 if (!network_configs_->GetDictionary(n, &info)) | 156 if (!network_configs_->GetDictionary(n, &info)) |
282 return NULL; | 157 return NULL; |
283 if (VLOG_IS_ON(2)) { | 158 // Parse Open Network Configuration blob into a temporary Network object. |
284 std::string network_json; | |
285 base::JSONWriter::Write(static_cast<base::Value*>(info), | |
286 true, &network_json); | |
287 VLOG(2) << "Parsing network at index " << n | |
288 << ": " << network_json; | |
289 } | |
290 | |
291 return CreateNetworkFromInfo(std::string(), *info); | 159 return CreateNetworkFromInfo(std::string(), *info); |
292 } | 160 } |
293 | 161 |
294 Network* OncNetworkParser::CreateNetworkFromInfo( | 162 Network* OncNetworkParser::CreateNetworkFromInfo( |
295 const std::string& service_path, | 163 const std::string& service_path, |
296 const DictionaryValue& info) { | 164 const DictionaryValue& info) { |
297 ConnectionType type = ParseTypeFromDictionary(info); | 165 ConnectionType type = ParseTypeFromDictionary(info); |
298 if (type == TYPE_UNKNOWN) // Return NULL if cannot parse network type. | 166 if (type == TYPE_UNKNOWN) // Return NULL if cannot parse network type. |
299 return NULL; | 167 return NULL; |
300 scoped_ptr<Network> network(CreateNewNetwork(type, service_path)); | 168 scoped_ptr<Network> network(CreateNewNetwork(type, service_path)); |
301 if (!ParseNestedObject(network.get(), | 169 // Update property with native value for type. |
302 "NetworkConfiguration", | 170 std::string str = NativeNetworkParser::network_type_mapper()->GetKey(type); |
303 static_cast<const base::Value&>(info), | 171 scoped_ptr<StringValue> val(Value::CreateStringValue(str)); |
304 network_configuration_signature, | 172 network->UpdatePropertyMap(PROPERTY_INDEX_TYPE, *val.get()); |
305 ParseNetworkConfigurationValue)) { | 173 |
306 LOG(WARNING) << "Network " << network->name() << " failed to parse."; | 174 // Get the child dictionary with properties for the network. |
| 175 // And copy all the values from this network type dictionary to parent. |
| 176 DictionaryValue* dict; |
| 177 if (!info.GetDictionary(GetTypeFromDictionary(info), &dict)) |
307 return NULL; | 178 return NULL; |
308 } | 179 |
309 if (VLOG_IS_ON(2)) { | 180 // Add GUID from the parent dictionary. |
310 VLOG(2) << "Created Network '" << network->name() | 181 dict->SetString("GUID", GetGuidFromDictionary(info)); |
311 << "' from info. Path:" << service_path | 182 |
312 << " Type:" << ConnectionTypeToString(type); | 183 UpdateNetworkFromInfo(*dict, network.get()); |
313 } | 184 VLOG(2) << "Created Network '" << network->name() |
| 185 << "' from info. Path:" << service_path |
| 186 << " Type:" << ConnectionTypeToString(type); |
314 return network.release(); | 187 return network.release(); |
315 } | 188 } |
316 | 189 |
317 Network* OncNetworkParser::CreateNewNetwork( | 190 Network* OncNetworkParser::CreateNewNetwork( |
318 ConnectionType type, const std::string& service_path) { | 191 ConnectionType type, const std::string& service_path) { |
319 Network* network = NetworkParser::CreateNewNetwork(type, service_path); | 192 Network* network = NetworkParser::CreateNewNetwork(type, service_path); |
320 if (network) { | 193 if (network) { |
321 if (type == TYPE_WIFI) | 194 if (type == TYPE_WIFI) |
322 network->SetNetworkParser(new OncWifiNetworkParser()); | 195 network->SetNetworkParser(new OncWifiNetworkParser()); |
323 else if (type == TYPE_VPN) | 196 else if (type == TYPE_VPN) |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
414 << net::ErrorToString(failures[0].net_error) | 287 << net::ErrorToString(failures[0].net_error) |
415 << ") importing " << cert_type << " certificate at index " | 288 << ") importing " << cert_type << " certificate at index " |
416 << cert_index; | 289 << cert_index; |
417 return false; | 290 return false; |
418 } | 291 } |
419 if (!success) { | 292 if (!success) { |
420 LOG(WARNING) << "ONC File: Unknown error importing " << cert_type | 293 LOG(WARNING) << "ONC File: Unknown error importing " << cert_type |
421 << " certificate at index " << cert_index; | 294 << " certificate at index " << cert_index; |
422 return false; | 295 return false; |
423 } | 296 } |
424 VLOG(2) << "Successfully imported server/ca certificate at index " | |
425 << cert_index; | |
426 return true; | 297 return true; |
427 } | 298 } |
428 | 299 |
429 bool OncNetworkParser::ParseClientCertificate( | 300 bool OncNetworkParser::ParseClientCertificate( |
430 int cert_index, | 301 int cert_index, |
431 base::DictionaryValue* certificate) { | 302 base::DictionaryValue* certificate) { |
432 net::CertDatabase cert_database; | 303 net::CertDatabase cert_database; |
433 std::string pkcs12_data; | 304 std::string pkcs12_data; |
434 if (!certificate->GetString("PKCS12", &pkcs12_data) || | 305 if (!certificate->GetString("PKCS12", &pkcs12_data) || |
435 pkcs12_data.empty()) { | 306 pkcs12_data.empty()) { |
(...skipping 12 matching lines...) Expand all Loading... |
448 // Since this has a private key, always use the private module. | 319 // Since this has a private key, always use the private module. |
449 scoped_refptr<net::CryptoModule> module(cert_database.GetPrivateModule()); | 320 scoped_refptr<net::CryptoModule> module(cert_database.GetPrivateModule()); |
450 int result = cert_database.ImportFromPKCS12( | 321 int result = cert_database.ImportFromPKCS12( |
451 module.get(), decoded_pkcs12, string16(), false); | 322 module.get(), decoded_pkcs12, string16(), false); |
452 if (result != net::OK) { | 323 if (result != net::OK) { |
453 LOG(WARNING) << "ONC File: Unable to import Client certificate at index " | 324 LOG(WARNING) << "ONC File: Unable to import Client certificate at index " |
454 << cert_index | 325 << cert_index |
455 << " (error " << net::ErrorToString(result) << ")."; | 326 << " (error " << net::ErrorToString(result) << ")."; |
456 return false; | 327 return false; |
457 } | 328 } |
458 VLOG(2) << "Successfully imported client certificate at index " | |
459 << cert_index; | |
460 return true; | 329 return true; |
461 } | 330 } |
462 | 331 |
463 bool OncNetworkParser::ParseNestedObject(Network* network, | |
464 const std::string& onc_type, | |
465 const base::Value& value, | |
466 OncValueSignature* signature, | |
467 ParserPointer parser) { | |
468 bool any_errors = false; | |
469 if (!value.IsType(base::Value::TYPE_DICTIONARY)) { | |
470 VLOG(1) << network->name() << ": expected object of type " << onc_type; | |
471 return false; | |
472 } | |
473 VLOG(2) << "Parsing nested object of type " << onc_type; | |
474 const DictionaryValue* dict = NULL; | |
475 value.GetAsDictionary(&dict); | |
476 for (DictionaryValue::key_iterator iter = dict->begin_keys(); | |
477 iter != dict->end_keys(); ++iter) { | |
478 const std::string& key = *iter; | |
479 base::Value* inner_value = NULL; | |
480 dict->GetWithoutPathExpansion(key, &inner_value); | |
481 CHECK(inner_value != NULL); | |
482 int field_index; | |
483 for (field_index = 0; signature[field_index].field != NULL; ++field_index) { | |
484 if (key == signature[field_index].field) | |
485 break; | |
486 } | |
487 if (signature[field_index].field == NULL) { | |
488 VLOG(1) << network->name() << ": unexpected field: " | |
489 << key << ", in type: " << onc_type; | |
490 any_errors = true; | |
491 continue; | |
492 } | |
493 if (!inner_value->IsType(signature[field_index].type)) { | |
494 VLOG(1) << network->name() << ": field with wrong type: " << key | |
495 << ", actual type: " << inner_value->GetType() | |
496 << ", expected type: " << signature[field_index].type; | |
497 any_errors = true; | |
498 continue; | |
499 } | |
500 PropertyIndex index = signature[field_index].index; | |
501 // We need to UpdatePropertyMap now since parser might want to | |
502 // change the mapped value. | |
503 network->UpdatePropertyMap(index, *inner_value); | |
504 if (!parser(this, index, *inner_value, network)) { | |
505 VLOG(1) << network->name() << ": field not parsed: " << key; | |
506 any_errors = true; | |
507 continue; | |
508 } | |
509 if (VLOG_IS_ON(2)) { | |
510 std::string value_json; | |
511 base::JSONWriter::Write(inner_value, true, &value_json); | |
512 VLOG(2) << network->name() << ": Successfully parsed [" << key | |
513 << "(" << index << ")] = " << value_json; | |
514 } | |
515 } | |
516 return !any_errors; | |
517 } | |
518 | |
519 // static | |
520 bool OncNetworkParser::CheckNetworkType(Network* network, | |
521 ConnectionType expected, | |
522 const std::string& onc_type) { | |
523 if (expected != network->type()) { | |
524 LOG(WARNING) << network->name() << ": " | |
525 << onc_type << " field unexpected for this type network"; | |
526 return false; | |
527 } | |
528 return true; | |
529 } | |
530 | |
531 // static | |
532 bool OncNetworkParser::ParseNetworkConfigurationValue( | |
533 OncNetworkParser* parser, | |
534 PropertyIndex index, | |
535 const base::Value& value, | |
536 Network* network) { | |
537 switch (index) { | |
538 case PROPERTY_INDEX_ONC_WIFI: { | |
539 return parser->ParseNestedObject(network, | |
540 "WiFi", | |
541 value, | |
542 wifi_signature, | |
543 OncWifiNetworkParser::ParseWifiValue); | |
544 } | |
545 case PROPERTY_INDEX_ONC_VPN: { | |
546 if (!CheckNetworkType(network, TYPE_VPN, "VPN")) | |
547 return false; | |
548 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); | |
549 // Got the "VPN" field. Immediately store the VPN.Type field | |
550 // value so that we can properly validate fields in the VPN | |
551 // object based on the type. | |
552 const DictionaryValue* dict = NULL; | |
553 CHECK(value.GetAsDictionary(&dict)); | |
554 std::string provider_type_string; | |
555 if (!dict->GetString("Type", &provider_type_string)) { | |
556 VLOG(1) << network->name() << ": VPN.Type is missing"; | |
557 return false; | |
558 } | |
559 ProviderType provider_type = | |
560 OncVirtualNetworkParser::ParseProviderType(provider_type_string); | |
561 virtual_network->set_provider_type(provider_type); | |
562 return parser->ParseNestedObject(network, | |
563 "VPN", | |
564 value, | |
565 vpn_signature, | |
566 OncVirtualNetworkParser::ParseVPNValue); | |
567 return true; | |
568 } | |
569 case PROPERTY_INDEX_ONC_REMOVE: | |
570 VLOG(1) << network->name() << ": Remove field not yet implemented"; | |
571 return false; | |
572 case PROPERTY_INDEX_TYPE: { | |
573 // Update property with native value for type. | |
574 std::string str = | |
575 NativeNetworkParser::network_type_mapper()->GetKey(network->type()); | |
576 scoped_ptr<StringValue> val(Value::CreateStringValue(str)); | |
577 network->UpdatePropertyMap(PROPERTY_INDEX_TYPE, *val.get()); | |
578 return true; | |
579 } | |
580 case PROPERTY_INDEX_GUID: | |
581 case PROPERTY_INDEX_NAME: | |
582 // Fall back to generic parser for these. | |
583 return parser->ParseValue(index, value, network); | |
584 default: | |
585 break; | |
586 } | |
587 return false; | |
588 } | |
589 | |
590 // -------------------- OncWirelessNetworkParser -------------------- | 332 // -------------------- OncWirelessNetworkParser -------------------- |
591 | 333 |
592 OncWirelessNetworkParser::OncWirelessNetworkParser() {} | 334 OncWirelessNetworkParser::OncWirelessNetworkParser() {} |
593 OncWirelessNetworkParser::~OncWirelessNetworkParser() {} | 335 OncWirelessNetworkParser::~OncWirelessNetworkParser() {} |
594 | 336 |
| 337 bool OncWirelessNetworkParser::ParseValue(PropertyIndex index, |
| 338 const base::Value& value, |
| 339 Network* network) { |
| 340 DCHECK_NE(TYPE_ETHERNET, network->type()); |
| 341 DCHECK_NE(TYPE_VPN, network->type()); |
| 342 return OncNetworkParser::ParseValue(index, value, network); |
| 343 } |
| 344 |
595 // -------------------- OncWifiNetworkParser -------------------- | 345 // -------------------- OncWifiNetworkParser -------------------- |
596 | 346 |
597 OncWifiNetworkParser::OncWifiNetworkParser() {} | 347 OncWifiNetworkParser::OncWifiNetworkParser() {} |
598 | |
599 OncWifiNetworkParser::~OncWifiNetworkParser() {} | 348 OncWifiNetworkParser::~OncWifiNetworkParser() {} |
600 | 349 |
601 // static | 350 bool OncWifiNetworkParser::ParseValue(PropertyIndex index, |
602 bool OncWifiNetworkParser::ParseWifiValue(OncNetworkParser* parser, | 351 const base::Value& value, |
603 PropertyIndex index, | 352 Network* network) { |
604 const base::Value& value, | 353 DCHECK_EQ(TYPE_WIFI, network->type()); |
605 Network* network) { | |
606 if (!CheckNetworkType(network, TYPE_WIFI, "WiFi")) | |
607 return false; | |
608 WifiNetwork* wifi_network = static_cast<WifiNetwork*>(network); | 354 WifiNetwork* wifi_network = static_cast<WifiNetwork*>(network); |
609 switch (index) { | 355 switch (index) { |
610 case PROPERTY_INDEX_SSID: | 356 case PROPERTY_INDEX_SSID: { |
611 wifi_network->SetName(GetStringValue(value)); | 357 std::string ssid; |
| 358 if (!value.GetAsString(&ssid)) |
| 359 break; |
| 360 wifi_network->SetName(ssid); |
612 return true; | 361 return true; |
| 362 } |
| 363 case PROPERTY_INDEX_GUID: { |
| 364 std::string unique_id; |
| 365 if (!value.GetAsString(&unique_id)) |
| 366 break; |
| 367 wifi_network->set_unique_id(unique_id); |
| 368 return true; |
| 369 } |
613 case PROPERTY_INDEX_SECURITY: { | 370 case PROPERTY_INDEX_SECURITY: { |
614 ConnectionSecurity security = ParseSecurity(GetStringValue(value)); | 371 std::string security_string; |
| 372 if (!value.GetAsString(&security_string)) |
| 373 break; |
| 374 ConnectionSecurity security = ParseSecurity(security_string); |
615 wifi_network->set_encryption(security); | 375 wifi_network->set_encryption(security); |
616 // Also update property with native value for security. | 376 // Also update property with native value for security. |
617 std::string str = | 377 std::string str = |
618 NativeNetworkParser::network_security_mapper()->GetKey(security); | 378 NativeNetworkParser::network_security_mapper()->GetKey(security); |
619 scoped_ptr<StringValue> val(Value::CreateStringValue(str)); | 379 scoped_ptr<StringValue> val(Value::CreateStringValue(str)); |
620 wifi_network->UpdatePropertyMap(index, *val.get()); | 380 wifi_network->UpdatePropertyMap(index, *val.get()); |
621 return true; | 381 return true; |
622 } | 382 } |
623 case PROPERTY_INDEX_PASSPHRASE: | 383 case PROPERTY_INDEX_PASSPHRASE: { |
624 wifi_network->set_passphrase(GetStringValue(value)); | 384 std::string passphrase; |
| 385 if (!value.GetAsString(&passphrase)) |
| 386 break; |
| 387 wifi_network->set_passphrase(passphrase); |
625 return true; | 388 return true; |
626 case PROPERTY_INDEX_IDENTITY: | 389 } |
627 wifi_network->set_identity(GetStringValue(value)); | 390 case PROPERTY_INDEX_IDENTITY: { |
| 391 std::string identity; |
| 392 if (!value.GetAsString(&identity)) |
| 393 break; |
| 394 wifi_network->set_identity(identity); |
628 return true; | 395 return true; |
629 case PROPERTY_INDEX_EAP: | 396 } |
630 parser->ParseNestedObject(wifi_network, | 397 case PROPERTY_INDEX_EAP: { |
631 "EAP", | 398 DCHECK_EQ(value.GetType(), Value::TYPE_DICTIONARY); |
632 value, | 399 const DictionaryValue& dict = static_cast<const DictionaryValue&>(value); |
633 eap_signature, | 400 for (DictionaryValue::key_iterator iter = dict.begin_keys(); |
634 ParseEAPValue); | 401 iter != dict.end_keys(); ++iter) { |
| 402 const std::string& key = *iter; |
| 403 base::Value* eap_value; |
| 404 bool res = dict.GetWithoutPathExpansion(key, &eap_value); |
| 405 DCHECK(res); |
| 406 if (res) { |
| 407 PropertyIndex index = mapper().Get(key); |
| 408 wifi_network->UpdatePropertyMap(index, *eap_value); |
| 409 if (!ParseEAPValue(index, *eap_value, wifi_network)) |
| 410 VLOG(1) << network->name() << ": EAP unhandled key: " << key |
| 411 << " Type: " << eap_value->GetType(); |
| 412 } |
| 413 } |
635 return true; | 414 return true; |
636 case PROPERTY_INDEX_AUTO_CONNECT: | 415 } |
637 network->set_auto_connect(GetBooleanValue(value)); | |
638 return true; | |
639 case PROPERTY_INDEX_HIDDEN_SSID: | |
640 // Pass this through to connection manager as is. | |
641 return true; | |
642 default: | 416 default: |
643 break; | 417 return OncWirelessNetworkParser::ParseValue(index, value, network); |
644 } | 418 } |
645 return false; | 419 return false; |
646 } | 420 } |
647 | 421 |
648 // static | 422 |
649 bool OncWifiNetworkParser::ParseEAPValue(OncNetworkParser*, | 423 bool OncWifiNetworkParser::ParseEAPValue(PropertyIndex index, |
650 PropertyIndex index, | |
651 const base::Value& value, | 424 const base::Value& value, |
652 Network* network) { | 425 WifiNetwork* wifi_network) { |
653 if (!CheckNetworkType(network, TYPE_WIFI, "EAP")) | |
654 return false; | |
655 WifiNetwork* wifi_network = static_cast<WifiNetwork*>(network); | |
656 switch (index) { | 426 switch (index) { |
657 case PROPERTY_INDEX_EAP_IDENTITY: | 427 case PROPERTY_INDEX_EAP_IDENTITY: { |
658 // TODO(crosbug.com/23751): Support string expansion. | 428 std::string eap_identity; |
659 wifi_network->set_eap_identity(GetStringValue(value)); | 429 if (!value.GetAsString(&eap_identity)) |
| 430 break; |
| 431 wifi_network->set_eap_identity(eap_identity); |
660 return true; | 432 return true; |
| 433 } |
661 case PROPERTY_INDEX_EAP_METHOD: { | 434 case PROPERTY_INDEX_EAP_METHOD: { |
662 EAPMethod eap_method = ParseEAPMethod(GetStringValue(value)); | 435 std::string eap_method_str; |
| 436 if (!value.GetAsString(&eap_method_str)) |
| 437 break; |
| 438 EAPMethod eap_method = ParseEAPMethod(eap_method_str); |
663 wifi_network->set_eap_method(eap_method); | 439 wifi_network->set_eap_method(eap_method); |
664 // Also update property with native value for EAP method. | 440 // Also update property with native value for EAP method. |
665 std::string str = | 441 std::string str = |
666 NativeNetworkParser::network_eap_method_mapper()->GetKey(eap_method); | 442 NativeNetworkParser::network_eap_method_mapper()->GetKey(eap_method); |
667 scoped_ptr<StringValue> val(Value::CreateStringValue(str)); | 443 scoped_ptr<StringValue> val(Value::CreateStringValue(str)); |
668 wifi_network->UpdatePropertyMap(index, *val.get()); | 444 wifi_network->UpdatePropertyMap(index, *val.get()); |
669 return true; | 445 return true; |
670 } | 446 } |
671 case PROPERTY_INDEX_EAP_PHASE_2_AUTH: { | 447 case PROPERTY_INDEX_EAP_PHASE_2_AUTH: { |
672 EAPPhase2Auth eap_phase_2_auth = ParseEAPPhase2Auth( | 448 std::string eap_phase_2_auth_str; |
673 GetStringValue(value)); | 449 if (!value.GetAsString(&eap_phase_2_auth_str)) |
| 450 break; |
| 451 EAPPhase2Auth eap_phase_2_auth = ParseEAPPhase2Auth(eap_phase_2_auth_str); |
674 wifi_network->set_eap_phase_2_auth(eap_phase_2_auth); | 452 wifi_network->set_eap_phase_2_auth(eap_phase_2_auth); |
675 // Also update property with native value for EAP phase 2 auth. | 453 // Also update property with native value for EAP phase 2 auth. |
676 std::string str = NativeNetworkParser::network_eap_auth_mapper()->GetKey( | 454 std::string str = NativeNetworkParser::network_eap_auth_mapper()->GetKey( |
677 eap_phase_2_auth); | 455 eap_phase_2_auth); |
678 scoped_ptr<StringValue> val(Value::CreateStringValue(str)); | 456 scoped_ptr<StringValue> val(Value::CreateStringValue(str)); |
679 wifi_network->UpdatePropertyMap(index, *val.get()); | 457 wifi_network->UpdatePropertyMap(index, *val.get()); |
680 return true; | 458 return true; |
681 } | 459 } |
682 case PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY: | 460 case PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY: { |
683 wifi_network->set_eap_anonymous_identity(GetStringValue(value)); | 461 std::string eap_anonymous_identity; |
| 462 if (!value.GetAsString(&eap_anonymous_identity)) |
| 463 break; |
| 464 wifi_network->set_eap_anonymous_identity(eap_anonymous_identity); |
684 return true; | 465 return true; |
685 case PROPERTY_INDEX_EAP_CERT_ID: | 466 } |
686 wifi_network->set_eap_client_cert_pkcs11_id(GetStringValue(value)); | 467 case PROPERTY_INDEX_EAP_CERT_ID: { |
| 468 std::string eap_client_cert_pkcs11_id; |
| 469 if (!value.GetAsString(&eap_client_cert_pkcs11_id)) |
| 470 break; |
| 471 wifi_network->set_eap_client_cert_pkcs11_id(eap_client_cert_pkcs11_id); |
687 return true; | 472 return true; |
688 case PROPERTY_INDEX_EAP_CA_CERT_NSS: | 473 } |
689 wifi_network->set_eap_server_ca_cert_nss_nickname(GetStringValue(value)); | 474 case PROPERTY_INDEX_EAP_CA_CERT_NSS: { |
| 475 std::string eap_server_ca_cert_nss_nickname; |
| 476 if (!value.GetAsString(&eap_server_ca_cert_nss_nickname)) |
| 477 break; |
| 478 wifi_network->set_eap_server_ca_cert_nss_nickname( |
| 479 eap_server_ca_cert_nss_nickname); |
690 return true; | 480 return true; |
691 case PROPERTY_INDEX_EAP_USE_SYSTEM_CAS: | 481 } |
692 wifi_network->set_eap_use_system_cas(GetBooleanValue(value)); | 482 case PROPERTY_INDEX_EAP_USE_SYSTEM_CAS: { |
| 483 bool eap_use_system_cas; |
| 484 if (!value.GetAsBoolean(&eap_use_system_cas)) |
| 485 break; |
| 486 wifi_network->set_eap_use_system_cas(eap_use_system_cas); |
693 return true; | 487 return true; |
694 case PROPERTY_INDEX_EAP_PASSWORD: | 488 } |
695 wifi_network->set_eap_passphrase(GetStringValue(value)); | 489 case PROPERTY_INDEX_EAP_PASSWORD: { |
| 490 std::string eap_passphrase; |
| 491 if (!value.GetAsString(&eap_passphrase)) |
| 492 break; |
| 493 wifi_network->set_eap_passphrase(eap_passphrase); |
696 return true; | 494 return true; |
697 case PROPERTY_INDEX_ONC_CLIENT_CERT_PATTERN: | 495 } |
698 case PROPERTY_INDEX_ONC_CLIENT_CERT_REF: | |
699 case PROPERTY_INDEX_ONC_CLIENT_CERT_TYPE: | |
700 // TODO(crosbug.com/19409): Support certificate patterns. | |
701 // Ignore for now. | |
702 return true; | |
703 default: | 496 default: |
704 break; | 497 break; |
705 } | 498 } |
706 return false; | 499 return false; |
707 } | 500 } |
708 | 501 |
709 // static | |
710 ConnectionSecurity OncWifiNetworkParser::ParseSecurity( | 502 ConnectionSecurity OncWifiNetworkParser::ParseSecurity( |
711 const std::string& security) { | 503 const std::string& security) { |
712 static EnumMapper<ConnectionSecurity>::Pair table[] = { | 504 static EnumMapper<ConnectionSecurity>::Pair table[] = { |
713 { "None", SECURITY_NONE }, | 505 { "None", SECURITY_NONE }, |
714 { "WEP-PSK", SECURITY_WEP }, | 506 { "WEP", SECURITY_WEP }, |
715 { "WPA-PSK", SECURITY_WPA }, | 507 { "WPA", SECURITY_WPA }, |
716 { "WPA-EAP", SECURITY_8021X }, | 508 { "WPA2", SECURITY_8021X }, |
717 }; | 509 }; |
718 CR_DEFINE_STATIC_LOCAL(EnumMapper<ConnectionSecurity>, parser, | 510 CR_DEFINE_STATIC_LOCAL(EnumMapper<ConnectionSecurity>, parser, |
719 (table, arraysize(table), SECURITY_UNKNOWN)); | 511 (table, arraysize(table), SECURITY_UNKNOWN)); |
720 return parser.Get(security); | 512 return parser.Get(security); |
721 } | 513 } |
722 | 514 |
723 // static | |
724 EAPMethod OncWifiNetworkParser::ParseEAPMethod(const std::string& method) { | 515 EAPMethod OncWifiNetworkParser::ParseEAPMethod(const std::string& method) { |
725 static EnumMapper<EAPMethod>::Pair table[] = { | 516 static EnumMapper<EAPMethod>::Pair table[] = { |
726 { "PEAP", EAP_METHOD_PEAP }, | 517 { "PEAP", EAP_METHOD_PEAP }, |
727 { "EAP-TLS", EAP_METHOD_TLS }, | 518 { "EAP-TLS", EAP_METHOD_TLS }, |
728 { "EAP-TTLS", EAP_METHOD_TTLS }, | 519 { "EAP-TTLS", EAP_METHOD_TTLS }, |
729 { "LEAP", EAP_METHOD_LEAP }, | 520 { "LEAP", EAP_METHOD_LEAP }, |
730 }; | 521 }; |
731 CR_DEFINE_STATIC_LOCAL(EnumMapper<EAPMethod>, parser, | 522 CR_DEFINE_STATIC_LOCAL(EnumMapper<EAPMethod>, parser, |
732 (table, arraysize(table), EAP_METHOD_UNKNOWN)); | 523 (table, arraysize(table), EAP_METHOD_UNKNOWN)); |
733 return parser.Get(method); | 524 return parser.Get(method); |
734 } | 525 } |
735 | 526 |
736 // static | |
737 EAPPhase2Auth OncWifiNetworkParser::ParseEAPPhase2Auth( | 527 EAPPhase2Auth OncWifiNetworkParser::ParseEAPPhase2Auth( |
738 const std::string& auth) { | 528 const std::string& auth) { |
739 static EnumMapper<EAPPhase2Auth>::Pair table[] = { | 529 static EnumMapper<EAPPhase2Auth>::Pair table[] = { |
740 { "MD5", EAP_PHASE_2_AUTH_MD5 }, | 530 { "MD5", EAP_PHASE_2_AUTH_MD5 }, |
741 { "MSCHAPV2", EAP_PHASE_2_AUTH_MSCHAPV2 }, | 531 { "MSCHAPV2", EAP_PHASE_2_AUTH_MSCHAPV2 }, |
742 { "MSCHAP", EAP_PHASE_2_AUTH_MSCHAP }, | 532 { "MSCHAP", EAP_PHASE_2_AUTH_MSCHAP }, |
743 { "PAP", EAP_PHASE_2_AUTH_PAP }, | 533 { "PAP", EAP_PHASE_2_AUTH_PAP }, |
744 }; | 534 }; |
745 CR_DEFINE_STATIC_LOCAL(EnumMapper<EAPPhase2Auth>, parser, | 535 CR_DEFINE_STATIC_LOCAL(EnumMapper<EAPPhase2Auth>, parser, |
746 (table, arraysize(table), EAP_PHASE_2_AUTH_AUTO)); | 536 (table, arraysize(table), EAP_PHASE_2_AUTH_AUTO)); |
(...skipping 10 matching lines...) Expand all Loading... |
757 const DictionaryValue& info, | 547 const DictionaryValue& info, |
758 Network* network) { | 548 Network* network) { |
759 DCHECK_EQ(TYPE_VPN, network->type()); | 549 DCHECK_EQ(TYPE_VPN, network->type()); |
760 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); | 550 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); |
761 if (!OncNetworkParser::UpdateNetworkFromInfo(info, network)) | 551 if (!OncNetworkParser::UpdateNetworkFromInfo(info, network)) |
762 return false; | 552 return false; |
763 VLOG(1) << "Updating VPN '" << virtual_network->name() | 553 VLOG(1) << "Updating VPN '" << virtual_network->name() |
764 << "': Server: " << virtual_network->server_hostname() | 554 << "': Server: " << virtual_network->server_hostname() |
765 << " Type: " | 555 << " Type: " |
766 << ProviderTypeToString(virtual_network->provider_type()); | 556 << ProviderTypeToString(virtual_network->provider_type()); |
| 557 if (virtual_network->provider_type() == PROVIDER_TYPE_L2TP_IPSEC_PSK) { |
| 558 if (!virtual_network->client_cert_id().empty()) |
| 559 virtual_network->set_provider_type(PROVIDER_TYPE_L2TP_IPSEC_USER_CERT); |
| 560 } |
767 return true; | 561 return true; |
768 } | 562 } |
769 | 563 |
770 // static | 564 bool OncVirtualNetworkParser::ParseValue(PropertyIndex index, |
771 bool OncVirtualNetworkParser::ParseVPNValue(OncNetworkParser* parser, | 565 const base::Value& value, |
772 PropertyIndex index, | 566 Network* network) { |
773 const base::Value& value, | 567 DCHECK_EQ(TYPE_VPN, network->type()); |
774 Network* network) { | |
775 if (!CheckNetworkType(network, TYPE_VPN, "VPN")) | |
776 return false; | |
777 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); | 568 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); |
778 switch (index) { | 569 switch (index) { |
779 case PROPERTY_INDEX_PROVIDER_HOST: { | 570 case PROPERTY_INDEX_PROVIDER: { |
780 virtual_network->set_server_hostname(GetStringValue(value)); | 571 DCHECK_EQ(value.GetType(), Value::TYPE_DICTIONARY); |
781 // Flimflam requires a domain property which is unused. | 572 const DictionaryValue& dict = static_cast<const DictionaryValue&>(value); |
782 network->UpdatePropertyMap(PROPERTY_INDEX_VPN_DOMAIN, | 573 for (DictionaryValue::key_iterator iter = dict.begin_keys(); |
783 base::StringValue("")); | 574 iter != dict.end_keys(); ++iter) { |
| 575 const std::string& key = *iter; |
| 576 base::Value* provider_value; |
| 577 bool res = dict.GetWithoutPathExpansion(key, &provider_value); |
| 578 DCHECK(res); |
| 579 if (res) { |
| 580 PropertyIndex index = mapper().Get(key); |
| 581 if (!ParseProviderValue(index, *provider_value, virtual_network)) |
| 582 VLOG(1) << network->name() << ": Provider unhandled key: " << key |
| 583 << " Type: " << provider_value->GetType(); |
| 584 } |
| 585 } |
784 return true; | 586 return true; |
785 } | 587 } |
786 case PROPERTY_INDEX_ONC_IPSEC: | 588 default: |
787 if (virtual_network->provider_type() != PROVIDER_TYPE_L2TP_IPSEC_PSK && | 589 return OncNetworkParser::ParseValue(index, value, network); |
788 virtual_network->provider_type() != | 590 break; |
789 PROVIDER_TYPE_L2TP_IPSEC_USER_CERT) { | 591 } |
790 VLOG(1) << "IPsec field not allowed with this VPN type"; | 592 return false; |
791 return false; | 593 } |
792 } | 594 |
793 return parser->ParseNestedObject(network, | 595 bool OncVirtualNetworkParser::ParseProviderValue(PropertyIndex index, |
794 "IPsec", | 596 const base::Value& value, |
795 value, | 597 VirtualNetwork* network) { |
796 ipsec_signature, | 598 switch (index) { |
797 ParseIPsecValue); | 599 case PROPERTY_INDEX_HOST: { |
798 case PROPERTY_INDEX_ONC_L2TP: | 600 std::string server_hostname; |
799 if (virtual_network->provider_type() != PROVIDER_TYPE_L2TP_IPSEC_PSK) { | 601 if (!value.GetAsString(&server_hostname)) |
800 VLOG(1) << "L2TP field not allowed with this VPN type"; | 602 break; |
801 return false; | 603 network->set_server_hostname(server_hostname); |
802 } | 604 return true; |
803 return parser->ParseNestedObject(network, | 605 } |
804 "L2TP", | 606 case PROPERTY_INDEX_NAME: { |
805 value, | 607 std::string name; |
806 l2tp_signature, | 608 if (!value.GetAsString(&name)) |
807 ParseL2TPValue); | 609 break; |
808 case PROPERTY_INDEX_ONC_OPENVPN: | 610 network->set_name(name); |
809 if (virtual_network->provider_type() != PROVIDER_TYPE_OPEN_VPN) { | 611 return true; |
810 VLOG(1) << "OpenVPN field not allowed with this VPN type"; | 612 } |
811 return false; | 613 case PROPERTY_INDEX_TYPE: { |
812 } | 614 std::string provider_type_string; |
813 // The following are needed by flimflam to set up the OpenVPN | 615 if (!value.GetAsString(&provider_type_string)) |
814 // management channel which every ONC OpenVPN configuration will | 616 break; |
815 // use. | 617 network->set_provider_type(ParseProviderType(provider_type_string)); |
816 network->UpdatePropertyMap(PROPERTY_INDEX_OPEN_VPN_AUTHUSERPASS, | 618 return true; |
817 StringValue("")); | 619 } |
818 network->UpdatePropertyMap(PROPERTY_INDEX_OPEN_VPN_MGMT_ENABLE, | 620 case PROPERTY_INDEX_L2TPIPSEC_CA_CERT_NSS: { |
819 StringValue("")); | 621 std::string ca_cert_nss; |
820 return parser->ParseNestedObject(network, | 622 if (!value.GetAsString(&ca_cert_nss)) |
821 "OpenVPN", | 623 break; |
822 value, | 624 network->set_ca_cert_nss(ca_cert_nss); |
823 openvpn_signature, | 625 return true; |
824 ParseOpenVPNValue); | 626 } |
825 case PROPERTY_INDEX_PROVIDER_TYPE: { | 627 case PROPERTY_INDEX_L2TPIPSEC_PSK: { |
826 // Update property with native value for provider type. | 628 std::string psk_passphrase; |
827 ProviderType provider_type = GetCanonicalProviderType( | 629 if (!value.GetAsString(&psk_passphrase)) |
828 virtual_network->provider_type()); | 630 break; |
829 std::string str = | 631 network->set_psk_passphrase(psk_passphrase); |
830 NativeVirtualNetworkParser::provider_type_mapper()->GetKey( | 632 return true; |
831 provider_type); | 633 } |
832 scoped_ptr<StringValue> val(Value::CreateStringValue(str)); | 634 case PROPERTY_INDEX_L2TPIPSEC_CLIENT_CERT_ID: { |
833 network->UpdatePropertyMap(PROPERTY_INDEX_PROVIDER_TYPE, *val.get()); | 635 std::string client_cert_id; |
| 636 if (!value.GetAsString(&client_cert_id)) |
| 637 break; |
| 638 network->set_client_cert_id(client_cert_id); |
| 639 return true; |
| 640 } |
| 641 case PROPERTY_INDEX_L2TPIPSEC_USER: { |
| 642 std::string username; |
| 643 if (!value.GetAsString(&username)) |
| 644 break; |
| 645 network->set_username(username); |
| 646 return true; |
| 647 } |
| 648 case PROPERTY_INDEX_L2TPIPSEC_PASSWORD: { |
| 649 std::string user_passphrase; |
| 650 if (!value.GetAsString(&user_passphrase)) |
| 651 break; |
| 652 network->set_user_passphrase(user_passphrase); |
| 653 return true; |
| 654 } |
| 655 case PROPERTY_INDEX_L2TPIPSEC_GROUP_NAME: { |
| 656 std::string group_name; |
| 657 if (!value.GetAsString(&group_name)) |
| 658 break; |
| 659 network->set_group_name(group_name); |
834 return true; | 660 return true; |
835 } | 661 } |
836 default: | 662 default: |
837 break; | 663 break; |
838 } | 664 } |
839 return false; | 665 return false; |
840 } | 666 } |
841 | 667 |
842 bool OncVirtualNetworkParser::ParseIPsecValue(OncNetworkParser* parser, | |
843 PropertyIndex index, | |
844 const base::Value& value, | |
845 Network* network) { | |
846 if (!CheckNetworkType(network, TYPE_VPN, "IPsec")) | |
847 return false; | |
848 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); | |
849 switch (index) { | |
850 case PROPERTY_INDEX_IPSEC_AUTHENTICATIONTYPE: | |
851 virtual_network->set_provider_type( | |
852 UpdateProviderTypeWithAuthType(virtual_network->provider_type(), | |
853 GetStringValue(value))); | |
854 return true; | |
855 case PROPERTY_INDEX_L2TPIPSEC_CA_CERT_NSS: | |
856 virtual_network->set_ca_cert_nss(GetStringValue(value)); | |
857 return true; | |
858 case PROPERTY_INDEX_L2TPIPSEC_PSK: | |
859 virtual_network->set_psk_passphrase(GetStringValue(value)); | |
860 return true; | |
861 case PROPERTY_INDEX_L2TPIPSEC_GROUP_NAME: | |
862 virtual_network->set_group_name(GetStringValue(value)); | |
863 return true; | |
864 case PROPERTY_INDEX_SAVE_CREDENTIALS: | |
865 // Note that the specification allows different settings for | |
866 // IPsec credentials (PSK) and L2TP credentials (username and | |
867 // password) but we merge them in our implementation as is required | |
868 // with the current connection manager. | |
869 virtual_network->set_save_credentials(GetBooleanValue(value)); | |
870 return true; | |
871 case PROPERTY_INDEX_ONC_CLIENT_CERT_PATTERN: | |
872 case PROPERTY_INDEX_ONC_CLIENT_CERT_REF: | |
873 case PROPERTY_INDEX_ONC_CLIENT_CERT_TYPE: | |
874 // TODO(crosbug.com/19409): Support certificate patterns. | |
875 // Ignore for now. | |
876 return true; | |
877 case PROPERTY_INDEX_IPSEC_IKEVERSION: | |
878 if (!value.IsType(TYPE_STRING)) { | |
879 // Flimflam wants all provider properties to be strings. | |
880 virtual_network->UpdatePropertyMap( | |
881 index, | |
882 StringValue(ConvertValueToString(value))); | |
883 } | |
884 return true; | |
885 default: | |
886 break; | |
887 } | |
888 return false; | |
889 } | |
890 | |
891 // static | |
892 ProviderType OncVirtualNetworkParser::UpdateProviderTypeWithAuthType( | |
893 ProviderType provider, | |
894 const std::string& auth_type) { | |
895 switch (provider) { | |
896 case PROVIDER_TYPE_L2TP_IPSEC_PSK: | |
897 case PROVIDER_TYPE_L2TP_IPSEC_USER_CERT: | |
898 if (auth_type == "Cert") { | |
899 return PROVIDER_TYPE_L2TP_IPSEC_USER_CERT; | |
900 } else { | |
901 if (auth_type != "PSK") { | |
902 VLOG(1) << "Unexpected authentication type " << auth_type; | |
903 break; | |
904 } | |
905 return PROVIDER_TYPE_L2TP_IPSEC_PSK; | |
906 } | |
907 default: | |
908 VLOG(1) << "Unexpected provider type with authentication type " | |
909 << auth_type; | |
910 break; | |
911 } | |
912 return provider; | |
913 } | |
914 | |
915 // static | |
916 ProviderType OncVirtualNetworkParser::GetCanonicalProviderType( | |
917 ProviderType provider_type) { | |
918 if (provider_type == PROVIDER_TYPE_L2TP_IPSEC_USER_CERT) | |
919 return PROVIDER_TYPE_L2TP_IPSEC_PSK; | |
920 return provider_type; | |
921 } | |
922 | |
923 // static | |
924 bool OncVirtualNetworkParser::ParseL2TPValue(OncNetworkParser*, | |
925 PropertyIndex index, | |
926 const base::Value& value, | |
927 Network* network) { | |
928 if (!CheckNetworkType(network, TYPE_VPN, "L2TP")) | |
929 return false; | |
930 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); | |
931 switch (index) { | |
932 case PROPERTY_INDEX_L2TPIPSEC_PASSWORD: | |
933 virtual_network->set_user_passphrase(GetStringValue(value)); | |
934 return true; | |
935 case PROPERTY_INDEX_L2TPIPSEC_USER: | |
936 // TODO(crosbug.com/23751): Support string expansion. | |
937 virtual_network->set_username(GetStringValue(value)); | |
938 return true; | |
939 case PROPERTY_INDEX_SAVE_CREDENTIALS: | |
940 // Note that the specification allows different settings for | |
941 // IPsec credentials (PSK) and L2TP credentials (username and | |
942 // password) but we merge them in our implementation as is required | |
943 // with the current connection manager. | |
944 virtual_network->set_save_credentials(GetBooleanValue(value)); | |
945 return true; | |
946 default: | |
947 break; | |
948 } | |
949 return false; | |
950 } | |
951 | |
952 // static | |
953 bool OncVirtualNetworkParser::ParseOpenVPNValue(OncNetworkParser*, | |
954 PropertyIndex index, | |
955 const base::Value& value, | |
956 Network* network) { | |
957 if (!CheckNetworkType(network, TYPE_VPN, "OpenVPN")) | |
958 return false; | |
959 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); | |
960 switch (index) { | |
961 case PROPERTY_INDEX_OPEN_VPN_PASSWORD: | |
962 virtual_network->set_user_passphrase(GetStringValue(value)); | |
963 return true; | |
964 case PROPERTY_INDEX_OPEN_VPN_USER: | |
965 // TODO(crosbug.com/23751): Support string expansion. | |
966 virtual_network->set_username(GetStringValue(value)); | |
967 return true; | |
968 case PROPERTY_INDEX_SAVE_CREDENTIALS: | |
969 virtual_network->set_save_credentials(GetBooleanValue(value)); | |
970 return true; | |
971 case PROPERTY_INDEX_OPEN_VPN_CACERT: | |
972 virtual_network->set_ca_cert_nss(GetStringValue(value)); | |
973 return true; | |
974 case PROPERTY_INDEX_OPEN_VPN_REMOTECERTKU: { | |
975 // ONC supports a list of these, but we flimflam supports only one | |
976 // today. So extract the first. | |
977 const base::ListValue* value_list = NULL; | |
978 value.GetAsList(&value_list); | |
979 base::Value* first_item = NULL; | |
980 if (!value_list->Get(0, &first_item) || | |
981 !first_item->IsType(base::Value::TYPE_STRING)) { | |
982 VLOG(1) << "RemoteCertKU must be non-empty list of strings"; | |
983 return false; | |
984 } | |
985 virtual_network->UpdatePropertyMap(index, *first_item); | |
986 return true; | |
987 } | |
988 case PROPERTY_INDEX_OPEN_VPN_AUTH: | |
989 case PROPERTY_INDEX_OPEN_VPN_AUTHRETRY: | |
990 case PROPERTY_INDEX_OPEN_VPN_AUTHNOCACHE: | |
991 case PROPERTY_INDEX_OPEN_VPN_CERT: | |
992 case PROPERTY_INDEX_OPEN_VPN_CIPHER: | |
993 case PROPERTY_INDEX_OPEN_VPN_COMPLZO: | |
994 case PROPERTY_INDEX_OPEN_VPN_COMPNOADAPT: | |
995 case PROPERTY_INDEX_OPEN_VPN_KEYDIRECTION: | |
996 case PROPERTY_INDEX_OPEN_VPN_NSCERTTYPE: | |
997 case PROPERTY_INDEX_OPEN_VPN_PORT: | |
998 case PROPERTY_INDEX_OPEN_VPN_PROTO: | |
999 case PROPERTY_INDEX_OPEN_VPN_PUSHPEERINFO: | |
1000 case PROPERTY_INDEX_OPEN_VPN_REMOTECERTEKU: | |
1001 case PROPERTY_INDEX_OPEN_VPN_REMOTECERTTLS: | |
1002 case PROPERTY_INDEX_OPEN_VPN_RENEGSEC: | |
1003 case PROPERTY_INDEX_OPEN_VPN_SERVERPOLLTIMEOUT: | |
1004 case PROPERTY_INDEX_OPEN_VPN_SHAPER: | |
1005 case PROPERTY_INDEX_OPEN_VPN_STATICCHALLENGE: | |
1006 case PROPERTY_INDEX_OPEN_VPN_TLSAUTHCONTENTS: | |
1007 case PROPERTY_INDEX_OPEN_VPN_TLSREMOTE: | |
1008 if (!value.IsType(TYPE_STRING)) { | |
1009 // Flimflam wants all provider properties to be strings. | |
1010 virtual_network->UpdatePropertyMap( | |
1011 index, | |
1012 StringValue(ConvertValueToString(value))); | |
1013 } | |
1014 return true; | |
1015 case PROPERTY_INDEX_ONC_CLIENT_CERT_PATTERN: | |
1016 case PROPERTY_INDEX_ONC_CLIENT_CERT_REF: | |
1017 case PROPERTY_INDEX_ONC_CLIENT_CERT_TYPE: | |
1018 // TODO(crosbug.com/19409): Support certificate patterns. | |
1019 // Ignore for now. | |
1020 return true; | |
1021 | |
1022 default: | |
1023 break; | |
1024 } | |
1025 return false; | |
1026 } | |
1027 | |
1028 // static | |
1029 ProviderType OncVirtualNetworkParser::ParseProviderType( | 668 ProviderType OncVirtualNetworkParser::ParseProviderType( |
1030 const std::string& type) { | 669 const std::string& type) { |
1031 static EnumMapper<ProviderType>::Pair table[] = { | 670 static EnumMapper<ProviderType>::Pair table[] = { |
1032 // We initially map to L2TP-IPsec PSK and then fix this up based | 671 { flimflam::kProviderL2tpIpsec, PROVIDER_TYPE_L2TP_IPSEC_PSK }, |
1033 // on the value of AuthenticationType. | 672 { flimflam::kProviderOpenVpn, PROVIDER_TYPE_OPEN_VPN }, |
1034 { "L2TP-IPsec", PROVIDER_TYPE_L2TP_IPSEC_PSK }, | |
1035 { "OpenVPN", PROVIDER_TYPE_OPEN_VPN }, | |
1036 }; | 673 }; |
1037 CR_DEFINE_STATIC_LOCAL(EnumMapper<ProviderType>, parser, | 674 CR_DEFINE_STATIC_LOCAL(EnumMapper<ProviderType>, parser, |
1038 (table, arraysize(table), PROVIDER_TYPE_MAX)); | 675 (table, arraysize(table), PROVIDER_TYPE_MAX)); |
1039 return parser.Get(type); | 676 return parser.Get(type); |
1040 } | 677 } |
1041 | 678 |
1042 } // namespace chromeos | 679 } // namespace chromeos |
OLD | NEW |