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