Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Side by Side Diff: chrome/browser/chromeos/cros/onc_network_parser.cc

Issue 8821023: Laning http://codereview.chromium.org/8759014/ on behalf of kmixter: (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/cros/onc_network_parser.h ('k') | chrome/browser/chromeos/cros/onc_network_parser_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698