OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/chromeos/cros/onc_network_parser.h" | |
6 | |
7 #include <keyhi.h> | |
8 #include <pk11pub.h> | |
9 | |
10 #include "base/base64.h" | |
11 #include "base/json/json_string_value_serializer.h" | |
12 #include "base/json/json_writer.h" // for debug output only. | |
13 #include "base/stringprintf.h" | |
14 #include "base/values.h" | |
15 #include "chrome/browser/chromeos/cros/certificate_pattern.h" | |
16 #include "chrome/browser/chromeos/cros/cros_library.h" | |
17 #include "chrome/browser/chromeos/cros/native_network_constants.h" | |
18 #include "chrome/browser/chromeos/cros/native_network_parser.h" | |
19 #include "chrome/browser/chromeos/cros/network_library.h" | |
20 #include "chrome/browser/chromeos/login/user_manager.h" | |
21 #include "chrome/browser/chromeos/proxy_config_service_impl.h" | |
22 #include "chrome/browser/prefs/proxy_config_dictionary.h" | |
23 #include "chrome/common/net/x509_certificate_model.h" | |
24 #include "chromeos/network/onc/onc_certificate_importer.h" | |
25 #include "chromeos/network/onc/onc_constants.h" | |
26 #include "chromeos/network/onc/onc_signature.h" | |
27 #include "chromeos/network/onc/onc_validator.h" | |
28 #include "content/public/browser/browser_thread.h" | |
29 #include "crypto/encryptor.h" | |
30 #include "crypto/hmac.h" | |
31 #include "crypto/scoped_nss_types.h" | |
32 #include "crypto/symmetric_key.h" | |
33 #include "grit/generated_resources.h" | |
34 #include "net/base/crypto_module.h" | |
35 #include "net/base/net_errors.h" | |
36 #include "net/base/nss_cert_database.h" | |
37 #include "net/base/pem_tokenizer.h" | |
38 #include "net/base/x509_certificate.h" | |
39 #include "net/proxy/proxy_bypass_rules.h" | |
40 #include "third_party/cros_system_api/dbus/service_constants.h" | |
41 #include "ui/base/l10n/l10n_util.h" | |
42 | |
43 namespace chromeos { | |
44 | |
45 // Local constants. | |
46 namespace { | |
47 | |
48 // The PEM block header used for DER certificates | |
49 const char kCertificateHeader[] = "CERTIFICATE"; | |
50 // This is an older PEM marker for DER certificates. | |
51 const char kX509CertificateHeader[] = "X509 CERTIFICATE"; | |
52 | |
53 const base::Value::Type TYPE_BOOLEAN = base::Value::TYPE_BOOLEAN; | |
54 const base::Value::Type TYPE_DICTIONARY = base::Value::TYPE_DICTIONARY; | |
55 const base::Value::Type TYPE_INTEGER = base::Value::TYPE_INTEGER; | |
56 const base::Value::Type TYPE_LIST = base::Value::TYPE_LIST; | |
57 const base::Value::Type TYPE_STRING = base::Value::TYPE_STRING; | |
58 | |
59 // Only used currently to keep NetworkParser superclass happy. | |
60 EnumMapper<PropertyIndex>::Pair network_configuration_table[] = { | |
61 { "GUID", PROPERTY_INDEX_GUID } | |
62 }; | |
63 | |
64 OncValueSignature network_configuration_signature[] = { | |
65 { onc::kGUID, PROPERTY_INDEX_GUID, TYPE_STRING }, | |
66 { onc::kProxySettings, PROPERTY_INDEX_ONC_PROXY_SETTINGS, TYPE_DICTIONARY }, | |
67 { onc::kName, PROPERTY_INDEX_NAME, TYPE_STRING }, | |
68 { onc::kRemove, PROPERTY_INDEX_ONC_REMOVE, TYPE_BOOLEAN }, | |
69 { onc::kType, PROPERTY_INDEX_TYPE, TYPE_STRING }, | |
70 { onc::kEthernet, PROPERTY_INDEX_ONC_ETHERNET, TYPE_DICTIONARY }, | |
71 { onc::kWiFi, PROPERTY_INDEX_ONC_WIFI, TYPE_DICTIONARY }, | |
72 { onc::kVPN, PROPERTY_INDEX_ONC_VPN, TYPE_DICTIONARY }, | |
73 { NULL } | |
74 }; | |
75 | |
76 OncValueSignature ethernet_signature[] = { | |
77 { onc::ethernet::kAuthentication, PROPERTY_INDEX_AUTHENTICATION, | |
78 TYPE_STRING }, | |
79 { onc::ethernet::kEAP, PROPERTY_INDEX_EAP, TYPE_DICTIONARY }, | |
80 { NULL } | |
81 }; | |
82 | |
83 OncValueSignature wifi_signature[] = { | |
84 { onc::wifi::kAutoConnect, PROPERTY_INDEX_AUTO_CONNECT, TYPE_BOOLEAN }, | |
85 { onc::wifi::kEAP, PROPERTY_INDEX_EAP, TYPE_DICTIONARY }, | |
86 { onc::wifi::kHiddenSSID, PROPERTY_INDEX_WIFI_HIDDEN_SSID, TYPE_BOOLEAN }, | |
87 { onc::wifi::kPassphrase, PROPERTY_INDEX_PASSPHRASE, TYPE_STRING }, | |
88 { onc::wifi::kSecurity, PROPERTY_INDEX_SECURITY, TYPE_STRING }, | |
89 { onc::wifi::kSSID, PROPERTY_INDEX_SSID, TYPE_STRING }, | |
90 { NULL } | |
91 }; | |
92 | |
93 OncValueSignature issuer_subject_pattern_signature[] = { | |
94 { onc::certificate::kCommonName, | |
95 PROPERTY_INDEX_ISSUER_SUBJECT_PATTERN_COMMON_NAME, TYPE_STRING }, | |
96 { onc::certificate::kLocality, | |
97 PROPERTY_INDEX_ISSUER_SUBJECT_PATTERN_LOCALITY, TYPE_STRING }, | |
98 { onc::certificate::kOrganization, | |
99 PROPERTY_INDEX_ISSUER_SUBJECT_PATTERN_ORGANIZATION, TYPE_STRING }, | |
100 { onc::certificate::kOrganizationalUnit, | |
101 PROPERTY_INDEX_ISSUER_SUBJECT_PATTERN_ORGANIZATIONAL_UNIT, | |
102 TYPE_STRING }, | |
103 }; | |
104 | |
105 OncValueSignature certificate_pattern_signature[] = { | |
106 { onc::certificate::kIssuerCARef, | |
107 PROPERTY_INDEX_ONC_CERTIFICATE_PATTERN_ISSUER_CA_REF, TYPE_LIST }, | |
108 { onc::certificate::kIssuer, | |
109 PROPERTY_INDEX_ONC_CERTIFICATE_PATTERN_ISSUER, TYPE_DICTIONARY }, | |
110 { onc::certificate::kSubject, | |
111 PROPERTY_INDEX_ONC_CERTIFICATE_PATTERN_SUBJECT, TYPE_DICTIONARY }, | |
112 { onc::certificate::kEnrollmentURI, | |
113 PROPERTY_INDEX_ONC_CERTIFICATE_PATTERN_ENROLLMENT_URI, TYPE_LIST }, | |
114 }; | |
115 | |
116 OncValueSignature eap_signature[] = { | |
117 { onc::eap::kAnonymousIdentity, PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY, | |
118 TYPE_STRING }, | |
119 { onc::eap::kClientCertPattern, PROPERTY_INDEX_ONC_CLIENT_CERT_PATTERN, | |
120 TYPE_DICTIONARY }, | |
121 { onc::eap::kClientCertRef, PROPERTY_INDEX_ONC_CLIENT_CERT_REF, TYPE_STRING }, | |
122 { onc::eap::kClientCertType, PROPERTY_INDEX_ONC_CLIENT_CERT_TYPE, | |
123 TYPE_STRING }, | |
124 { onc::eap::kIdentity, PROPERTY_INDEX_EAP_IDENTITY, TYPE_STRING }, | |
125 { onc::eap::kInner, PROPERTY_INDEX_EAP_PHASE_2_AUTH, TYPE_STRING }, | |
126 { onc::eap::kOuter, PROPERTY_INDEX_EAP_METHOD, TYPE_STRING }, | |
127 { onc::eap::kPassword, PROPERTY_INDEX_EAP_PASSWORD, TYPE_STRING }, | |
128 { onc::eap::kServerCARef, PROPERTY_INDEX_EAP_CA_CERT_NSS, TYPE_STRING }, | |
129 { onc::eap::kUseSystemCAs, PROPERTY_INDEX_EAP_USE_SYSTEM_CAS, TYPE_BOOLEAN }, | |
130 { onc::eap::kSaveCredentials, PROPERTY_INDEX_SAVE_CREDENTIALS, TYPE_BOOLEAN }, | |
131 { NULL } | |
132 }; | |
133 | |
134 OncValueSignature vpn_signature[] = { | |
135 { onc::vpn::kHost, PROPERTY_INDEX_PROVIDER_HOST, TYPE_STRING }, | |
136 { onc::vpn::kIPsec, PROPERTY_INDEX_ONC_IPSEC, TYPE_DICTIONARY }, | |
137 { onc::vpn::kL2TP, PROPERTY_INDEX_ONC_L2TP, TYPE_DICTIONARY }, | |
138 { onc::vpn::kOpenVPN, PROPERTY_INDEX_ONC_OPENVPN, TYPE_DICTIONARY }, | |
139 { onc::vpn::kType, PROPERTY_INDEX_PROVIDER_TYPE, TYPE_STRING }, | |
140 { NULL } | |
141 }; | |
142 | |
143 OncValueSignature ipsec_signature[] = { | |
144 { onc::vpn::kAuthenticationType, PROPERTY_INDEX_IPSEC_AUTHENTICATIONTYPE, | |
145 TYPE_STRING }, | |
146 { onc::vpn::kGroup, PROPERTY_INDEX_L2TPIPSEC_GROUP_NAME, TYPE_STRING }, | |
147 { onc::vpn::kIKEVersion, PROPERTY_INDEX_IPSEC_IKEVERSION, TYPE_INTEGER }, | |
148 { onc::vpn::kClientCertPattern, PROPERTY_INDEX_ONC_CLIENT_CERT_PATTERN, | |
149 TYPE_DICTIONARY }, | |
150 { onc::vpn::kClientCertRef, PROPERTY_INDEX_ONC_CLIENT_CERT_REF, TYPE_STRING }, | |
151 { onc::vpn::kClientCertType, PROPERTY_INDEX_ONC_CLIENT_CERT_TYPE, | |
152 TYPE_STRING }, | |
153 // Note: EAP and XAUTH not yet supported. | |
154 { onc::vpn::kPSK, PROPERTY_INDEX_L2TPIPSEC_PSK, TYPE_STRING }, | |
155 { onc::vpn::kSaveCredentials, PROPERTY_INDEX_SAVE_CREDENTIALS, TYPE_BOOLEAN }, | |
156 { onc::vpn::kServerCARef, PROPERTY_INDEX_L2TPIPSEC_CA_CERT_NSS, TYPE_STRING }, | |
157 { NULL } | |
158 }; | |
159 | |
160 OncValueSignature l2tp_signature[] = { | |
161 { onc::vpn::kPassword, PROPERTY_INDEX_L2TPIPSEC_PASSWORD, TYPE_STRING }, | |
162 { onc::vpn::kSaveCredentials, PROPERTY_INDEX_SAVE_CREDENTIALS, TYPE_BOOLEAN }, | |
163 { onc::vpn::kUsername, PROPERTY_INDEX_L2TPIPSEC_USER, TYPE_STRING }, | |
164 { NULL } | |
165 }; | |
166 | |
167 OncValueSignature openvpn_signature[] = { | |
168 { onc::vpn::kAuth, PROPERTY_INDEX_OPEN_VPN_AUTH, TYPE_STRING }, | |
169 { onc::vpn::kAuthRetry, PROPERTY_INDEX_OPEN_VPN_AUTHRETRY, TYPE_STRING }, | |
170 { onc::vpn::kAuthNoCache, PROPERTY_INDEX_OPEN_VPN_AUTHNOCACHE, TYPE_BOOLEAN }, | |
171 { onc::vpn::kCipher, PROPERTY_INDEX_OPEN_VPN_CIPHER, TYPE_STRING }, | |
172 { onc::vpn::kClientCertPattern, PROPERTY_INDEX_ONC_CLIENT_CERT_PATTERN, | |
173 TYPE_DICTIONARY }, | |
174 { onc::vpn::kClientCertRef, PROPERTY_INDEX_ONC_CLIENT_CERT_REF, TYPE_STRING }, | |
175 { onc::vpn::kClientCertType, PROPERTY_INDEX_ONC_CLIENT_CERT_TYPE, | |
176 TYPE_STRING }, | |
177 { onc::vpn::kCompLZO, PROPERTY_INDEX_OPEN_VPN_COMPLZO, TYPE_STRING }, | |
178 { onc::vpn::kCompNoAdapt, PROPERTY_INDEX_OPEN_VPN_COMPNOADAPT, TYPE_BOOLEAN }, | |
179 { onc::vpn::kKeyDirection, PROPERTY_INDEX_OPEN_VPN_KEYDIRECTION, | |
180 TYPE_STRING }, | |
181 { onc::vpn::kNsCertType, PROPERTY_INDEX_OPEN_VPN_NSCERTTYPE, TYPE_STRING }, | |
182 { onc::vpn::kPassword, PROPERTY_INDEX_OPEN_VPN_PASSWORD, TYPE_STRING }, | |
183 { onc::vpn::kPort, PROPERTY_INDEX_OPEN_VPN_PORT, TYPE_INTEGER }, | |
184 { onc::vpn::kProto, PROPERTY_INDEX_OPEN_VPN_PROTO, TYPE_STRING }, | |
185 { onc::vpn::kPushPeerInfo, PROPERTY_INDEX_OPEN_VPN_PUSHPEERINFO, | |
186 TYPE_BOOLEAN }, | |
187 { onc::vpn::kRemoteCertEKU, PROPERTY_INDEX_OPEN_VPN_REMOTECERTEKU, | |
188 TYPE_STRING }, | |
189 { onc::vpn::kRemoteCertKU, PROPERTY_INDEX_OPEN_VPN_REMOTECERTKU, TYPE_LIST }, | |
190 { onc::vpn::kRemoteCertTLS, PROPERTY_INDEX_OPEN_VPN_REMOTECERTTLS, | |
191 TYPE_STRING }, | |
192 { onc::vpn::kRenegSec, PROPERTY_INDEX_OPEN_VPN_RENEGSEC, TYPE_INTEGER }, | |
193 { onc::vpn::kSaveCredentials, PROPERTY_INDEX_SAVE_CREDENTIALS, TYPE_BOOLEAN }, | |
194 { onc::vpn::kServerCARef, PROPERTY_INDEX_OPEN_VPN_CACERT, TYPE_STRING }, | |
195 { onc::vpn::kServerCertRef, PROPERTY_INDEX_OPEN_VPN_CERT, TYPE_STRING }, | |
196 { onc::vpn::kServerPollTimeout, PROPERTY_INDEX_OPEN_VPN_SERVERPOLLTIMEOUT, | |
197 TYPE_INTEGER }, | |
198 { onc::vpn::kShaper, PROPERTY_INDEX_OPEN_VPN_SHAPER, TYPE_INTEGER }, | |
199 { onc::vpn::kStaticChallenge, PROPERTY_INDEX_OPEN_VPN_STATICCHALLENGE, | |
200 TYPE_STRING }, | |
201 { onc::vpn::kTLSAuthContents, PROPERTY_INDEX_OPEN_VPN_TLSAUTHCONTENTS, | |
202 TYPE_STRING }, | |
203 { onc::vpn::kTLSRemote, PROPERTY_INDEX_OPEN_VPN_TLSREMOTE, TYPE_STRING }, | |
204 { onc::vpn::kUsername, PROPERTY_INDEX_OPEN_VPN_USER, TYPE_STRING }, | |
205 { NULL } | |
206 }; | |
207 | |
208 OncValueSignature proxy_settings_signature[] = { | |
209 { onc::proxy::kType, PROPERTY_INDEX_ONC_PROXY_TYPE, TYPE_STRING }, | |
210 { onc::proxy::kPAC, PROPERTY_INDEX_ONC_PROXY_PAC, TYPE_STRING }, | |
211 { onc::proxy::kManual, PROPERTY_INDEX_ONC_PROXY_MANUAL, TYPE_DICTIONARY }, | |
212 { onc::proxy::kExcludeDomains, PROPERTY_INDEX_ONC_PROXY_EXCLUDE_DOMAINS, | |
213 TYPE_LIST }, | |
214 { NULL }, | |
215 }; | |
216 | |
217 OncValueSignature proxy_manual_signature[] = { | |
218 { onc::proxy::kHttp, PROPERTY_INDEX_ONC_PROXY_HTTP, TYPE_DICTIONARY }, | |
219 { onc::proxy::kHttps, PROPERTY_INDEX_ONC_PROXY_HTTPS, TYPE_DICTIONARY }, | |
220 { onc::proxy::kFtp, PROPERTY_INDEX_ONC_PROXY_FTP, TYPE_DICTIONARY }, | |
221 { onc::proxy::kSocks, PROPERTY_INDEX_ONC_PROXY_SOCKS, TYPE_DICTIONARY }, | |
222 { NULL }, | |
223 }; | |
224 | |
225 // Serve the singleton mapper instance. | |
226 const EnumMapper<PropertyIndex>* get_onc_mapper() { | |
227 CR_DEFINE_STATIC_LOCAL(const EnumMapper<PropertyIndex>, mapper, | |
228 (network_configuration_table, | |
229 arraysize(network_configuration_table), | |
230 PROPERTY_INDEX_UNKNOWN)); | |
231 return &mapper; | |
232 } | |
233 | |
234 ConnectionType ParseNetworkType(const std::string& type) { | |
235 static EnumMapper<ConnectionType>::Pair table[] = { | |
236 { "Ethernet", TYPE_ETHERNET }, | |
237 { "WiFi", TYPE_WIFI }, | |
238 { "VPN", TYPE_VPN }, | |
239 }; | |
240 CR_DEFINE_STATIC_LOCAL(EnumMapper<ConnectionType>, parser, | |
241 (table, arraysize(table), TYPE_UNKNOWN)); | |
242 return parser.Get(type); | |
243 } | |
244 | |
245 std::string GetStringValue(const base::Value& value) { | |
246 std::string string_value; | |
247 value.GetAsString(&string_value); | |
248 return string_value; | |
249 } | |
250 | |
251 const bool GetBooleanValue(const base::Value& value) { | |
252 bool bool_value = false; | |
253 value.GetAsBoolean(&bool_value); | |
254 return bool_value; | |
255 } | |
256 | |
257 std::string ConvertValueToString(const base::Value& value) { | |
258 std::string value_json; | |
259 base::JSONWriter::Write(&value, &value_json); | |
260 return value_json; | |
261 } | |
262 | |
263 bool GetAsListOfStrings(const base::Value& value, | |
264 std::vector<std::string>* result) { | |
265 const base::ListValue* list = NULL; | |
266 if (!value.GetAsList(&list)) | |
267 return false; | |
268 result->clear(); | |
269 result->reserve(list->GetSize()); | |
270 for (size_t i = 0; i < list->GetSize(); i++) { | |
271 std::string item; | |
272 if (!list->GetString(i, &item)) | |
273 return false; | |
274 result->push_back(item); | |
275 } | |
276 return true; | |
277 } | |
278 | |
279 } // namespace | |
280 | |
281 // -------------------- OncNetworkParser -------------------- | |
282 | |
283 OncNetworkParser::OncNetworkParser(const base::ListValue& network_configs, | |
284 onc::ONCSource onc_source) | |
285 : NetworkParser(get_onc_mapper()), | |
286 onc_source_(onc_source), | |
287 network_configs_(network_configs.DeepCopy()) { | |
288 } | |
289 | |
290 OncNetworkParser::OncNetworkParser() | |
291 : NetworkParser(get_onc_mapper()), | |
292 network_configs_(NULL) { | |
293 } | |
294 | |
295 OncNetworkParser::~OncNetworkParser() { | |
296 } | |
297 | |
298 // static | |
299 const EnumMapper<PropertyIndex>* OncNetworkParser::property_mapper() { | |
300 return get_onc_mapper(); | |
301 } | |
302 | |
303 int OncNetworkParser::GetNetworkConfigsSize() const { | |
304 return network_configs_ ? network_configs_->GetSize() : 0; | |
305 } | |
306 | |
307 const base::DictionaryValue* OncNetworkParser::GetNetworkConfig(int n) { | |
308 CHECK(network_configs_); | |
309 CHECK(static_cast<size_t>(n) < network_configs_->GetSize()); | |
310 CHECK_GE(n, 0); | |
311 base::DictionaryValue* info = NULL; | |
312 if (!network_configs_->GetDictionary(n, &info)) { | |
313 parse_error_ = l10n_util::GetStringUTF8( | |
314 IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); | |
315 return NULL; | |
316 } | |
317 | |
318 return info; | |
319 } | |
320 | |
321 Network* OncNetworkParser::ParseNetwork(int n, bool* marked_for_removal) { | |
322 const base::DictionaryValue* info = GetNetworkConfig(n); | |
323 if (!info) | |
324 return NULL; | |
325 | |
326 if (VLOG_IS_ON(2)) { | |
327 std::string network_json; | |
328 base::JSONWriter::WriteWithOptions(static_cast<const base::Value*>(info), | |
329 base::JSONWriter::OPTIONS_PRETTY_PRINT, | |
330 &network_json); | |
331 VLOG(2) << "Parsing network at index " << n << ": " << network_json; | |
332 } | |
333 | |
334 if (marked_for_removal) { | |
335 if (!info->GetBoolean(onc::kRemove, marked_for_removal)) | |
336 *marked_for_removal = false; | |
337 } | |
338 | |
339 return CreateNetworkFromInfo(std::string(), *info); | |
340 } | |
341 | |
342 Network* OncNetworkParser::CreateNetworkFromInfo( | |
343 const std::string& service_path, | |
344 const DictionaryValue& info) { | |
345 ConnectionType type = ParseTypeFromDictionary(info); | |
346 if (type == TYPE_UNKNOWN) { // Return NULL if cannot parse network type. | |
347 parse_error_ = l10n_util::GetStringUTF8( | |
348 IDS_NETWORK_CONFIG_ERROR_NETWORK_TYPE_MISSING); | |
349 return NULL; | |
350 } | |
351 scoped_ptr<Network> network(CreateNewNetwork(type, service_path)); | |
352 | |
353 // Initialize ONC source. | |
354 NetworkUIData ui_data = network->ui_data(); | |
355 ui_data.set_onc_source(onc_source_); | |
356 network->set_ui_data(ui_data); | |
357 | |
358 // Parse all properties recursively. | |
359 if (!ParseNestedObject(network.get(), | |
360 onc::kNetworkConfiguration, | |
361 static_cast<const base::Value&>(info), | |
362 network_configuration_signature, | |
363 ParseNetworkConfigurationValue)) { | |
364 LOG(WARNING) << "Network " << network->name() << " failed to parse."; | |
365 if (parse_error_.empty()) | |
366 parse_error_ = l10n_util::GetStringUTF8( | |
367 IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); | |
368 return NULL; | |
369 } | |
370 | |
371 // Update the UI data property in shill. | |
372 std::string ui_data_json; | |
373 base::DictionaryValue ui_data_dict; | |
374 network->ui_data().FillDictionary(&ui_data_dict); | |
375 base::JSONWriter::Write(&ui_data_dict, &ui_data_json); | |
376 base::StringValue ui_data_string_value(ui_data_json); | |
377 network->UpdatePropertyMap(PROPERTY_INDEX_UI_DATA, &ui_data_string_value); | |
378 | |
379 if (VLOG_IS_ON(2)) { | |
380 VLOG(2) << "Created Network '" << network->name() | |
381 << "' from info. Path:" << service_path | |
382 << " Type:" << ConnectionTypeToString(type); | |
383 } | |
384 | |
385 return network.release(); | |
386 } | |
387 | |
388 bool OncNetworkParser::ParseNestedObject(Network* network, | |
389 const std::string& onc_type, | |
390 const base::Value& value, | |
391 OncValueSignature* signature, | |
392 ParserPointer parser) { | |
393 bool any_errors = false; | |
394 if (!value.IsType(base::Value::TYPE_DICTIONARY)) { | |
395 VLOG(1) << network->name() << ": expected object of type " << onc_type; | |
396 parse_error_ = l10n_util::GetStringUTF8( | |
397 IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); | |
398 return false; | |
399 } | |
400 VLOG(2) << "Parsing nested object of type " << onc_type; | |
401 const DictionaryValue* dict = NULL; | |
402 value.GetAsDictionary(&dict); | |
403 for (DictionaryValue::key_iterator iter = dict->begin_keys(); | |
404 iter != dict->end_keys(); ++iter) { | |
405 const std::string& key = *iter; | |
406 | |
407 // Recommended keys are only of interest to the UI code and the UI reads it | |
408 // directly from the ONC blob. | |
409 if (key == onc::kRecommended) | |
410 continue; | |
411 | |
412 const base::Value* inner_value = NULL; | |
413 dict->GetWithoutPathExpansion(key, &inner_value); | |
414 CHECK(inner_value != NULL); | |
415 int field_index; | |
416 for (field_index = 0; signature[field_index].field != NULL; ++field_index) { | |
417 if (key == signature[field_index].field) | |
418 break; | |
419 } | |
420 if (signature[field_index].field == NULL) { | |
421 LOG(WARNING) << network->name() << ": unexpected field: " | |
422 << key << ", in type: " << onc_type; | |
423 continue; | |
424 } | |
425 if (!inner_value->IsType(signature[field_index].type)) { | |
426 LOG(ERROR) << network->name() << ": field with wrong type: " << key | |
427 << ", actual type: " << inner_value->GetType() | |
428 << ", expected type: " << signature[field_index].type; | |
429 any_errors = true; | |
430 continue; | |
431 } | |
432 PropertyIndex index = signature[field_index].index; | |
433 // We need to UpdatePropertyMap now since parser might want to | |
434 // change the mapped value. | |
435 network->UpdatePropertyMap(index, inner_value); | |
436 if (!parser(this, index, *inner_value, network)) { | |
437 LOG(ERROR) << network->name() << ": field in " << onc_type | |
438 << " not parsed: " << key; | |
439 any_errors = true; | |
440 continue; | |
441 } | |
442 if (VLOG_IS_ON(2)) { | |
443 std::string value_json; | |
444 base::JSONWriter::WriteWithOptions(inner_value, | |
445 base::JSONWriter::OPTIONS_PRETTY_PRINT, | |
446 &value_json); | |
447 VLOG(2) << network->name() << ": Successfully parsed [" << key | |
448 << "(" << index << ")] = " << value_json; | |
449 } | |
450 } | |
451 if (any_errors) { | |
452 parse_error_ = l10n_util::GetStringUTF8( | |
453 IDS_NETWORK_CONFIG_ERROR_NETWORK_PROP_DICT_MALFORMED); | |
454 } | |
455 return !any_errors; | |
456 } | |
457 | |
458 // static | |
459 std::string OncNetworkParser::GetUserExpandedValue( | |
460 const base::Value& value, | |
461 onc::ONCSource source) { | |
462 std::string string_value; | |
463 if (!value.GetAsString(&string_value)) | |
464 return string_value; | |
465 | |
466 // If running unit test, just return the original value. | |
467 if (!content::BrowserThread::IsMessageLoopValid(content::BrowserThread::UI)) | |
468 return string_value; | |
469 | |
470 if (source != onc::ONC_SOURCE_USER_POLICY && | |
471 source != onc::ONC_SOURCE_USER_IMPORT) { | |
472 return string_value; | |
473 } | |
474 | |
475 if (!UserManager::Get()->IsUserLoggedIn()) | |
476 return string_value; | |
477 | |
478 const User* logged_in_user = UserManager::Get()->GetLoggedInUser(); | |
479 ReplaceSubstringsAfterOffset(&string_value, 0, | |
480 onc::substitutes::kLoginIDField, | |
481 logged_in_user->GetAccountName(false)); | |
482 ReplaceSubstringsAfterOffset(&string_value, 0, | |
483 onc::substitutes::kEmailField, | |
484 logged_in_user->email()); | |
485 return string_value; | |
486 } | |
487 | |
488 Network* OncNetworkParser::CreateNewNetwork( | |
489 ConnectionType type, const std::string& service_path) { | |
490 Network* network = NetworkParser::CreateNewNetwork(type, service_path); | |
491 if (network) { | |
492 if (type == TYPE_ETHERNET) | |
493 network->SetNetworkParser(new OncEthernetNetworkParser()); | |
494 else if (type == TYPE_WIFI) | |
495 network->SetNetworkParser(new OncWifiNetworkParser()); | |
496 else if (type == TYPE_VPN) | |
497 network->SetNetworkParser(new OncVirtualNetworkParser()); | |
498 } | |
499 return network; | |
500 } | |
501 | |
502 ConnectionType OncNetworkParser::ParseType(const std::string& type) { | |
503 return ParseNetworkType(type); | |
504 } | |
505 | |
506 ConnectionType OncNetworkParser::ParseTypeFromDictionary( | |
507 const DictionaryValue& info) { | |
508 return ParseType(GetTypeFromDictionary(info)); | |
509 } | |
510 | |
511 std::string OncNetworkParser::GetTypeFromDictionary( | |
512 const base::DictionaryValue& info) { | |
513 std::string type_string; | |
514 info.GetString("Type", &type_string); | |
515 return type_string; | |
516 } | |
517 | |
518 std::string OncNetworkParser::GetGuidFromDictionary( | |
519 const base::DictionaryValue& info) { | |
520 std::string guid_string; | |
521 info.GetString("GUID", &guid_string); | |
522 return guid_string; | |
523 } | |
524 | |
525 // static | |
526 bool OncNetworkParser::ParseNetworkConfigurationValue( | |
527 OncNetworkParser* parser, | |
528 PropertyIndex index, | |
529 const base::Value& value, | |
530 Network* network) { | |
531 switch (index) { | |
532 case PROPERTY_INDEX_ONC_ETHERNET: | |
533 return parser->ParseNestedObject(network, "Ethernet", value, | |
534 ethernet_signature, OncEthernetNetworkParser::ParseEthernetValue); | |
535 case PROPERTY_INDEX_ONC_WIFI: | |
536 return parser->ParseNestedObject(network, | |
537 onc::kWiFi, | |
538 value, | |
539 wifi_signature, | |
540 OncWifiNetworkParser::ParseWifiValue); | |
541 case PROPERTY_INDEX_ONC_VPN: { | |
542 if (!CheckNetworkType(network, TYPE_VPN, onc::kVPN)) | |
543 return false; | |
544 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); | |
545 // Got the "VPN" field. Immediately store the VPN.Type field | |
546 // value so that we can properly validate fields in the VPN | |
547 // object based on the type. | |
548 const DictionaryValue* dict = NULL; | |
549 CHECK(value.GetAsDictionary(&dict)); | |
550 std::string provider_type_string; | |
551 if (!dict->GetString("Type", &provider_type_string)) { | |
552 VLOG(1) << network->name() << ": VPN.Type is missing"; | |
553 return false; | |
554 } | |
555 ProviderType provider_type = | |
556 OncVirtualNetworkParser::ParseProviderType(provider_type_string); | |
557 virtual_network->set_provider_type(provider_type); | |
558 return parser->ParseNestedObject(network, | |
559 onc::kVPN, | |
560 value, | |
561 vpn_signature, | |
562 OncVirtualNetworkParser::ParseVPNValue); | |
563 } | |
564 case PROPERTY_INDEX_ONC_PROXY_SETTINGS: | |
565 return ProcessProxySettings(parser, value, network); | |
566 case PROPERTY_INDEX_ONC_REMOVE: | |
567 // Removal is handled in ParseNetwork, and so is ignored here. | |
568 return true; | |
569 case PROPERTY_INDEX_TYPE: { | |
570 // Update property with native value for type. | |
571 std::string str = | |
572 NativeNetworkParser::network_type_mapper()->GetKey(network->type()); | |
573 base::StringValue val(str); | |
574 network->UpdatePropertyMap(PROPERTY_INDEX_TYPE, &val); | |
575 return true; | |
576 } | |
577 case PROPERTY_INDEX_GUID: | |
578 // Fall back to generic parser. | |
579 return parser->ParseValue(index, value, network); | |
580 case PROPERTY_INDEX_NAME: | |
581 // shill doesn't allow setting name for non-VPN networks. | |
582 if (network->type() != TYPE_VPN) { | |
583 network->UpdatePropertyMap(PROPERTY_INDEX_NAME, NULL); | |
584 return true; | |
585 } | |
586 | |
587 // Fall back to generic parser. | |
588 return parser->ParseValue(index, value, network); | |
589 default: | |
590 break; | |
591 } | |
592 return false; | |
593 } | |
594 | |
595 // static | |
596 bool OncNetworkParser::CheckNetworkType(Network* network, | |
597 ConnectionType expected, | |
598 const std::string& onc_type) { | |
599 if (expected != network->type()) { | |
600 LOG(WARNING) << network->name() << ": " | |
601 << onc_type << " field unexpected for this type network"; | |
602 return false; | |
603 } | |
604 return true; | |
605 } | |
606 | |
607 // static | |
608 ClientCertType OncNetworkParser::ParseClientCertType( | |
609 const std::string& type) { | |
610 static EnumMapper<ClientCertType>::Pair table[] = { | |
611 { onc::certificate::kNone, CLIENT_CERT_TYPE_NONE }, | |
612 { onc::certificate::kRef, CLIENT_CERT_TYPE_REF }, | |
613 { onc::certificate::kPattern, CLIENT_CERT_TYPE_PATTERN }, | |
614 }; | |
615 CR_DEFINE_STATIC_LOCAL(EnumMapper<ClientCertType>, parser, | |
616 (table, arraysize(table), CLIENT_CERT_TYPE_NONE)); | |
617 return parser.Get(type); | |
618 } | |
619 | |
620 // static | |
621 std::string OncNetworkParser::GetPkcs11IdFromCertGuid(const std::string& guid) { | |
622 // We have to look up the GUID to find the PKCS#11 ID that is needed. | |
623 net::CertificateList cert_list; | |
624 onc::CertificateImporter::ListCertsWithNickname(guid, &cert_list); | |
625 DCHECK_EQ(1ul, cert_list.size()); | |
626 if (cert_list.size() == 1) | |
627 return x509_certificate_model::GetPkcs11Id(cert_list[0]->os_cert_handle()); | |
628 return std::string(); | |
629 } | |
630 | |
631 // static | |
632 bool OncNetworkParser::ProcessProxySettings(OncNetworkParser* parser, | |
633 const base::Value& value, | |
634 Network* network) { | |
635 VLOG(1) << "Processing ProxySettings: " << ConvertValueToString(value); | |
636 | |
637 // Got "ProxySettings" field. Immediately store the ProxySettings.Type | |
638 // field value so that we can properly validate fields in the ProxySettings | |
639 // object based on the type. | |
640 const DictionaryValue* dict = NULL; | |
641 CHECK(value.GetAsDictionary(&dict)); | |
642 std::string proxy_type_string; | |
643 if (!dict->GetString(onc::proxy::kType, &proxy_type_string)) { | |
644 VLOG(1) << network->name() << ": ProxySettings.Type is missing"; | |
645 return false; | |
646 } | |
647 Network::ProxyOncConfig& config = network->proxy_onc_config(); | |
648 config.type = ParseProxyType(proxy_type_string); | |
649 | |
650 // For Direct and WPAD, all other fields are ignored. | |
651 // Otherwise, recursively parse the children of ProxySettings dictionary. | |
652 if (config.type != PROXY_ONC_DIRECT && config.type != PROXY_ONC_WPAD) { | |
653 if (!parser->ParseNestedObject(network, | |
654 onc::kProxySettings, | |
655 value, | |
656 proxy_settings_signature, | |
657 OncNetworkParser::ParseProxySettingsValue)) { | |
658 return false; | |
659 } | |
660 } | |
661 | |
662 // Create ProxyConfigDictionary based on parsed values. | |
663 scoped_ptr<DictionaryValue> proxy_dict; | |
664 switch (config.type) { | |
665 case PROXY_ONC_DIRECT: { | |
666 proxy_dict.reset(ProxyConfigDictionary::CreateDirect()); | |
667 break; | |
668 } | |
669 case PROXY_ONC_WPAD: { | |
670 proxy_dict.reset(ProxyConfigDictionary::CreateAutoDetect()); | |
671 break; | |
672 } | |
673 case PROXY_ONC_PAC: { | |
674 if (config.pac_url.empty()) { | |
675 VLOG(1) << "PAC field is required for this ProxySettings.Type"; | |
676 return false; | |
677 } | |
678 GURL url(config.pac_url); | |
679 if (!url.is_valid()) { | |
680 VLOG(1) << "PAC field is invalid for this ProxySettings.Type"; | |
681 return false; | |
682 } | |
683 proxy_dict.reset(ProxyConfigDictionary::CreatePacScript(url.spec(), | |
684 false)); | |
685 break; | |
686 } | |
687 case PROXY_ONC_MANUAL: { | |
688 if (config.manual_spec.empty()) { | |
689 VLOG(1) << "Manual field is required for this ProxySettings.Type"; | |
690 return false; | |
691 } | |
692 proxy_dict.reset(ProxyConfigDictionary::CreateFixedServers( | |
693 config.manual_spec, config.bypass_rules)); | |
694 break; | |
695 } | |
696 default: | |
697 break; | |
698 } | |
699 if (!proxy_dict.get()) | |
700 return false; | |
701 | |
702 // Serialize ProxyConfigDictionary into a string. | |
703 std::string proxy_dict_str = ConvertValueToString(*proxy_dict.get()); | |
704 | |
705 // Add ProxyConfig property to property map so that it will be updated in | |
706 // shill in NetworkLibraryImplCros::CallConfigureService after all parsing | |
707 // has completed. | |
708 base::StringValue val(proxy_dict_str); | |
709 network->UpdatePropertyMap(PROPERTY_INDEX_PROXY_CONFIG, &val); | |
710 | |
711 // If |network| is currently being connected to or it exists in memory, | |
712 // shill will fire PropertyChanged notification in ConfigureService, | |
713 // chromeos::ProxyConfigServiceImpl will get OnNetworkChanged notification | |
714 // and, if necessary, activate |proxy_dict_str| on network stack and reflect | |
715 // it in UI via "Change proxy settings" button. | |
716 network->set_proxy_config(proxy_dict_str); | |
717 VLOG(1) << "Parsed ProxyConfig: " << network->proxy_config(); | |
718 | |
719 return true; | |
720 } | |
721 | |
722 // static | |
723 bool OncNetworkParser::ParseProxySettingsValue(OncNetworkParser* parser, | |
724 PropertyIndex index, | |
725 const base::Value& value, | |
726 Network* network) { | |
727 Network::ProxyOncConfig& config = network->proxy_onc_config(); | |
728 switch (index) { | |
729 case PROPERTY_INDEX_ONC_PROXY_PAC: { | |
730 if (config.type == PROXY_ONC_PAC) { | |
731 // This is a string specifying the url. | |
732 config.pac_url = GetStringValue(value); | |
733 return true; | |
734 } | |
735 break; | |
736 } | |
737 case PROPERTY_INDEX_ONC_PROXY_MANUAL: { | |
738 if (config.type == PROXY_ONC_MANUAL) { | |
739 // Recursively parse the children of Manual dictionary. | |
740 return parser->ParseNestedObject(network, | |
741 onc::proxy::kManual, | |
742 value, | |
743 proxy_manual_signature, | |
744 ParseProxyManualValue); | |
745 } | |
746 break; | |
747 } | |
748 case PROPERTY_INDEX_ONC_PROXY_EXCLUDE_DOMAINS: { | |
749 if (config.type == PROXY_ONC_MANUAL) { | |
750 // This is a list of rules, parse them into ProxyBypassRules. | |
751 net::ProxyBypassRules rules; | |
752 const ListValue* list = NULL; | |
753 CHECK(value.GetAsList(&list)); | |
754 for (size_t i = 0; i < list->GetSize(); ++i) { | |
755 std::string val; | |
756 if (!list->GetString(i, &val)) | |
757 return false; | |
758 rules.AddRuleFromString(val); | |
759 } | |
760 config.bypass_rules = rules.ToString(); | |
761 return true; | |
762 } | |
763 break; | |
764 } | |
765 default: | |
766 break; | |
767 } | |
768 return true; | |
769 } | |
770 | |
771 // static | |
772 ProxyOncType OncNetworkParser::ParseProxyType(const std::string& type) { | |
773 static EnumMapper<ProxyOncType>::Pair table[] = { | |
774 { onc::proxy::kDirect, PROXY_ONC_DIRECT }, | |
775 { onc::proxy::kWPAD, PROXY_ONC_WPAD }, | |
776 { onc::proxy::kPAC, PROXY_ONC_PAC }, | |
777 { onc::proxy::kManual, PROXY_ONC_MANUAL }, | |
778 }; | |
779 | |
780 CR_DEFINE_STATIC_LOCAL(EnumMapper<ProxyOncType>, parser, | |
781 (table, arraysize(table), PROXY_ONC_MAX)); | |
782 | |
783 return parser.Get(type); | |
784 } | |
785 | |
786 // static | |
787 bool OncNetworkParser::ParseProxyManualValue(OncNetworkParser* parser, | |
788 PropertyIndex index, | |
789 const base::Value& value, | |
790 Network* network) { | |
791 switch (index) { | |
792 case PROPERTY_INDEX_ONC_PROXY_HTTP: | |
793 return ParseProxyServer(index, value, "http", network); | |
794 break; | |
795 case PROPERTY_INDEX_ONC_PROXY_HTTPS: | |
796 return ParseProxyServer(index, value, "https", network); | |
797 break; | |
798 case PROPERTY_INDEX_ONC_PROXY_FTP: | |
799 return ParseProxyServer(index, value, "ftp", network); | |
800 break; | |
801 case PROPERTY_INDEX_ONC_PROXY_SOCKS: | |
802 return ParseProxyServer(index, value, "socks", network); | |
803 break; | |
804 default: | |
805 break; | |
806 } | |
807 return false; | |
808 } | |
809 | |
810 // static | |
811 bool OncNetworkParser::ParseProxyServer(int property_index, | |
812 const base::Value& value, | |
813 const std::string& scheme, | |
814 Network* network) { | |
815 // Parse the ProxyLocation dictionary that specifies the proxy server. | |
816 net::ProxyServer server = ParseProxyLocationValue(property_index, value); | |
817 if (!server.is_valid()) | |
818 return false; | |
819 | |
820 // Append proxy server info to manual spec string. | |
821 ProxyConfigServiceImpl::ProxyConfig::EncodeAndAppendProxyServer(scheme, | |
822 server, &network->proxy_onc_config().manual_spec); | |
823 return true; | |
824 } | |
825 | |
826 // static | |
827 net::ProxyServer OncNetworkParser::ParseProxyLocationValue( | |
828 int property_index, | |
829 const base::Value& value) { | |
830 // Extract the values of Host and Port keys in ProxyLocation dictionary. | |
831 const DictionaryValue* dict = NULL; | |
832 CHECK(value.GetAsDictionary(&dict)); | |
833 std::string host; | |
834 int port = 0; | |
835 if (!(dict->GetString(onc::proxy::kHost, &host) && | |
836 dict->GetInteger(onc::proxy::kPort, &port))) { | |
837 return net::ProxyServer(); | |
838 } | |
839 | |
840 // Determine the scheme for the proxy server. | |
841 net::ProxyServer::Scheme scheme = net::ProxyServer::SCHEME_HTTP; | |
842 if (property_index == PROPERTY_INDEX_ONC_PROXY_SOCKS) { | |
843 scheme = StartsWithASCII(host, "socks5://", false) ? | |
844 net::ProxyServer::SCHEME_SOCKS5 : net::ProxyServer::SCHEME_SOCKS4; | |
845 } | |
846 | |
847 // Process the Host and Port values into net::HostPortPair, and then | |
848 // net::ProxyServer for the specific scheme. | |
849 net::HostPortPair host_port(host, static_cast<uint16>(port)); | |
850 return net::ProxyServer(scheme, host_port); | |
851 } | |
852 | |
853 // static | |
854 bool OncNetworkParser::ParseClientCertPattern(OncNetworkParser* parser, | |
855 PropertyIndex index, | |
856 const base::Value& value, | |
857 Network* network) { | |
858 // Ignore certificate patterns for device policy ONC so that an unmanaged user | |
859 // won't have a certificate presented for them involuntarily. | |
860 if (parser->onc_source() == onc::ONC_SOURCE_DEVICE_POLICY) | |
861 return false; | |
862 | |
863 // Only WiFi and VPN have this type. | |
864 if (network->type() != TYPE_WIFI && | |
865 network->type() != TYPE_VPN) { | |
866 LOG(WARNING) << "Tried to parse a ClientCertPattern from something " | |
867 << "that wasn't a WiFi or VPN network."; | |
868 return false; | |
869 } | |
870 | |
871 | |
872 switch (index) { | |
873 case PROPERTY_INDEX_ONC_CERTIFICATE_PATTERN_ENROLLMENT_URI: { | |
874 std::vector<std::string> resulting_list; | |
875 if (!GetAsListOfStrings(value, &resulting_list)) | |
876 return false; | |
877 CertificatePattern pattern = network->client_cert_pattern(); | |
878 pattern.set_enrollment_uri_list(resulting_list); | |
879 network->set_client_cert_pattern(pattern); | |
880 return true; | |
881 } | |
882 case PROPERTY_INDEX_ONC_CERTIFICATE_PATTERN_ISSUER_CA_REF: { | |
883 std::vector<std::string> resulting_list; | |
884 if (!GetAsListOfStrings(value, &resulting_list)) | |
885 return false; | |
886 CertificatePattern pattern = network->client_cert_pattern(); | |
887 pattern.set_issuer_ca_ref_list(resulting_list); | |
888 network->set_client_cert_pattern(pattern); | |
889 return true; | |
890 } | |
891 case PROPERTY_INDEX_ONC_CERTIFICATE_PATTERN_ISSUER: | |
892 return parser->ParseNestedObject(network, | |
893 onc::certificate::kIssuer, | |
894 value, | |
895 issuer_subject_pattern_signature, | |
896 ParseIssuerPattern); | |
897 case PROPERTY_INDEX_ONC_CERTIFICATE_PATTERN_SUBJECT: | |
898 return parser->ParseNestedObject(network, | |
899 onc::certificate::kSubject, | |
900 value, | |
901 issuer_subject_pattern_signature, | |
902 ParseSubjectPattern); | |
903 default: | |
904 break; | |
905 } | |
906 return false; | |
907 } | |
908 | |
909 // static | |
910 bool OncNetworkParser::ParseIssuerPattern(OncNetworkParser* parser, | |
911 PropertyIndex index, | |
912 const base::Value& value, | |
913 Network* network) { | |
914 IssuerSubjectPattern pattern; | |
915 if (ParseIssuerSubjectPattern(&pattern, parser, index, value, network)) { | |
916 CertificatePattern cert_pattern = network->client_cert_pattern(); | |
917 cert_pattern.set_issuer(pattern); | |
918 network->set_client_cert_pattern(cert_pattern); | |
919 return true; | |
920 } | |
921 return false; | |
922 } | |
923 | |
924 // static | |
925 bool OncNetworkParser::ParseSubjectPattern(OncNetworkParser* parser, | |
926 PropertyIndex index, | |
927 const base::Value& value, | |
928 Network* network) { | |
929 IssuerSubjectPattern pattern; | |
930 if (ParseIssuerSubjectPattern(&pattern, parser, index, value, network)) { | |
931 CertificatePattern cert_pattern = network->client_cert_pattern(); | |
932 cert_pattern.set_subject(pattern); | |
933 network->set_client_cert_pattern(cert_pattern); | |
934 return true; | |
935 } | |
936 return false; | |
937 } | |
938 | |
939 // static | |
940 bool OncNetworkParser::ParseIssuerSubjectPattern(IssuerSubjectPattern* pattern, | |
941 OncNetworkParser* parser, | |
942 PropertyIndex index, | |
943 const base::Value& value, | |
944 Network* network) { | |
945 // Only WiFi and VPN have this type. | |
946 if (network->type() != TYPE_WIFI && | |
947 network->type() != TYPE_VPN) { | |
948 LOG(WARNING) << "Tried to parse an IssuerSubjectPattern from something " | |
949 << "that wasn't a WiFi or VPN network."; | |
950 return false; | |
951 } | |
952 std::string value_str; | |
953 if (!value.GetAsString(&value_str)) | |
954 return false; | |
955 | |
956 bool result = false; | |
957 switch (index) { | |
958 case PROPERTY_INDEX_ISSUER_SUBJECT_PATTERN_COMMON_NAME: | |
959 pattern->set_common_name(value_str); | |
960 result = true; | |
961 break; | |
962 case PROPERTY_INDEX_ISSUER_SUBJECT_PATTERN_LOCALITY: | |
963 pattern->set_locality(value_str); | |
964 result = true; | |
965 break; | |
966 case PROPERTY_INDEX_ISSUER_SUBJECT_PATTERN_ORGANIZATION: | |
967 pattern->set_organization(value_str); | |
968 result = true; | |
969 break; | |
970 case PROPERTY_INDEX_ISSUER_SUBJECT_PATTERN_ORGANIZATIONAL_UNIT: | |
971 pattern->set_organizational_unit(value_str); | |
972 result = true; | |
973 break; | |
974 default: | |
975 break; | |
976 } | |
977 return result; | |
978 } | |
979 | |
980 // -------------------- OncEthernetNetworkParser -------------------- | |
981 | |
982 OncEthernetNetworkParser::OncEthernetNetworkParser() {} | |
983 OncEthernetNetworkParser::~OncEthernetNetworkParser() {} | |
984 | |
985 bool OncEthernetNetworkParser::ParseEthernetValue(OncNetworkParser* parser, | |
986 PropertyIndex index, | |
987 const base::Value& value, | |
988 Network* network) { | |
989 if (!CheckNetworkType(network, TYPE_ETHERNET, "Ethernet")) | |
990 return false; | |
991 // EthernetNetwork* ethernet_network = static_cast<EthernetNetwork*>(network); | |
992 switch (index) { | |
993 case PROPERTY_INDEX_AUTHENTICATION: | |
994 // TODO(chocobo): Handle authentication. | |
995 return true; | |
996 case PROPERTY_INDEX_EAP: | |
997 // TODO(chocobo): Implement EAP authentication. | |
998 return true; | |
999 default: | |
1000 break; | |
1001 } | |
1002 return false; | |
1003 } | |
1004 | |
1005 // -------------------- OncWirelessNetworkParser -------------------- | |
1006 | |
1007 OncWirelessNetworkParser::OncWirelessNetworkParser() {} | |
1008 OncWirelessNetworkParser::~OncWirelessNetworkParser() {} | |
1009 | |
1010 // -------------------- OncWifiNetworkParser -------------------- | |
1011 | |
1012 OncWifiNetworkParser::OncWifiNetworkParser() {} | |
1013 OncWifiNetworkParser::~OncWifiNetworkParser() {} | |
1014 | |
1015 // static | |
1016 bool OncWifiNetworkParser::ParseWifiValue(OncNetworkParser* parser, | |
1017 PropertyIndex index, | |
1018 const base::Value& value, | |
1019 Network* network) { | |
1020 if (!CheckNetworkType(network, TYPE_WIFI, "WiFi")) | |
1021 return false; | |
1022 WifiNetwork* wifi_network = static_cast<WifiNetwork*>(network); | |
1023 switch (index) { | |
1024 case PROPERTY_INDEX_SSID: | |
1025 wifi_network->SetName(GetStringValue(value)); | |
1026 return true; | |
1027 case PROPERTY_INDEX_SECURITY: { | |
1028 ConnectionSecurity security = ParseSecurity(GetStringValue(value)); | |
1029 wifi_network->set_encryption(security); | |
1030 // Also update property with native value for security. | |
1031 base::StringValue val( | |
1032 NativeNetworkParser::network_security_mapper()->GetKey(security)); | |
1033 wifi_network->UpdatePropertyMap(index, &val); | |
1034 return true; | |
1035 } | |
1036 case PROPERTY_INDEX_PASSPHRASE: | |
1037 wifi_network->set_passphrase(GetStringValue(value)); | |
1038 return true; | |
1039 case PROPERTY_INDEX_IDENTITY: | |
1040 wifi_network->set_identity(GetStringValue(value)); | |
1041 return true; | |
1042 case PROPERTY_INDEX_EAP: | |
1043 parser->ParseNestedObject(wifi_network, | |
1044 onc::wifi::kEAP, | |
1045 value, | |
1046 eap_signature, | |
1047 ParseEAPValue); | |
1048 return true; | |
1049 case PROPERTY_INDEX_AUTO_CONNECT: | |
1050 network->set_auto_connect(GetBooleanValue(value)); | |
1051 return true; | |
1052 case PROPERTY_INDEX_WIFI_HIDDEN_SSID: | |
1053 wifi_network->set_hidden_ssid(GetBooleanValue(value)); | |
1054 return true; | |
1055 default: | |
1056 break; | |
1057 } | |
1058 return false; | |
1059 } | |
1060 | |
1061 // static | |
1062 bool OncWifiNetworkParser::ParseEAPValue(OncNetworkParser* parser, | |
1063 PropertyIndex index, | |
1064 const base::Value& value, | |
1065 Network* network) { | |
1066 if (!CheckNetworkType(network, TYPE_WIFI, onc::wifi::kEAP)) | |
1067 return false; | |
1068 WifiNetwork* wifi_network = static_cast<WifiNetwork*>(network); | |
1069 switch (index) { | |
1070 case PROPERTY_INDEX_EAP_IDENTITY: { | |
1071 const std::string expanded_identity( | |
1072 GetUserExpandedValue(value, parser->onc_source())); | |
1073 wifi_network->set_eap_identity(expanded_identity); | |
1074 const StringValue expanded_identity_value(expanded_identity); | |
1075 wifi_network->UpdatePropertyMap(index, &expanded_identity_value); | |
1076 return true; | |
1077 } | |
1078 case PROPERTY_INDEX_EAP_METHOD: { | |
1079 EAPMethod eap_method = ParseEAPMethod(GetStringValue(value)); | |
1080 wifi_network->set_eap_method(eap_method); | |
1081 // Also update property with native value for EAP method. | |
1082 base::StringValue val( | |
1083 NativeNetworkParser::network_eap_method_mapper()->GetKey(eap_method)); | |
1084 wifi_network->UpdatePropertyMap(index, &val); | |
1085 return true; | |
1086 } | |
1087 case PROPERTY_INDEX_EAP_PHASE_2_AUTH: { | |
1088 EAPPhase2Auth eap_phase_2_auth = ParseEAPPhase2Auth( | |
1089 GetStringValue(value)); | |
1090 wifi_network->set_eap_phase_2_auth(eap_phase_2_auth); | |
1091 // Also update property with native value for EAP phase 2 auth. | |
1092 base::StringValue val( | |
1093 NativeNetworkParser::network_eap_auth_mapper()->GetKey( | |
1094 eap_phase_2_auth)); | |
1095 wifi_network->UpdatePropertyMap(index, &val); | |
1096 return true; | |
1097 } | |
1098 case PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY: { | |
1099 const std::string expanded_identity( | |
1100 GetUserExpandedValue(value, parser->onc_source())); | |
1101 wifi_network->set_eap_anonymous_identity(expanded_identity); | |
1102 const StringValue expanded_identity_value(expanded_identity); | |
1103 wifi_network->UpdatePropertyMap(index, &expanded_identity_value); | |
1104 return true; | |
1105 } | |
1106 case PROPERTY_INDEX_EAP_CERT_ID: | |
1107 wifi_network->set_eap_client_cert_pkcs11_id(GetStringValue(value)); | |
1108 return true; | |
1109 case PROPERTY_INDEX_EAP_CA_CERT_NSS: | |
1110 wifi_network->set_eap_server_ca_cert_nss_nickname(GetStringValue(value)); | |
1111 return true; | |
1112 case PROPERTY_INDEX_EAP_USE_SYSTEM_CAS: | |
1113 wifi_network->set_eap_use_system_cas(GetBooleanValue(value)); | |
1114 return true; | |
1115 case PROPERTY_INDEX_EAP_PASSWORD: | |
1116 wifi_network->set_eap_passphrase(GetStringValue(value)); | |
1117 return true; | |
1118 case PROPERTY_INDEX_ONC_CLIENT_CERT_REF: { | |
1119 std::string cert_id = GetPkcs11IdFromCertGuid(GetStringValue(value)); | |
1120 if (cert_id.empty()) | |
1121 return false; | |
1122 wifi_network->set_eap_client_cert_pkcs11_id(cert_id); | |
1123 return true; | |
1124 } | |
1125 case PROPERTY_INDEX_ONC_CLIENT_CERT_PATTERN: | |
1126 return parser->ParseNestedObject( | |
1127 wifi_network, | |
1128 onc::eap::kClientCertPattern, | |
1129 value, | |
1130 certificate_pattern_signature, | |
1131 OncNetworkParser::ParseClientCertPattern); | |
1132 case PROPERTY_INDEX_ONC_CLIENT_CERT_TYPE: { | |
1133 ClientCertType type = ParseClientCertType(GetStringValue(value)); | |
1134 wifi_network->set_client_cert_type(type); | |
1135 return true; | |
1136 } | |
1137 case PROPERTY_INDEX_SAVE_CREDENTIALS: | |
1138 wifi_network->set_eap_save_credentials(GetBooleanValue(value)); | |
1139 return true; | |
1140 default: | |
1141 break; | |
1142 } | |
1143 return false; | |
1144 } | |
1145 | |
1146 // static | |
1147 ConnectionSecurity OncWifiNetworkParser::ParseSecurity( | |
1148 const std::string& security) { | |
1149 static EnumMapper<ConnectionSecurity>::Pair table[] = { | |
1150 { "None", SECURITY_NONE }, | |
1151 { "WEP-PSK", SECURITY_WEP }, | |
1152 { "WPA-PSK", SECURITY_PSK }, | |
1153 { "WPA-EAP", SECURITY_8021X }, | |
1154 }; | |
1155 CR_DEFINE_STATIC_LOCAL(EnumMapper<ConnectionSecurity>, parser, | |
1156 (table, arraysize(table), SECURITY_UNKNOWN)); | |
1157 return parser.Get(security); | |
1158 } | |
1159 | |
1160 // static | |
1161 EAPMethod OncWifiNetworkParser::ParseEAPMethod(const std::string& method) { | |
1162 static EnumMapper<EAPMethod>::Pair table[] = { | |
1163 { "PEAP", EAP_METHOD_PEAP }, | |
1164 { "EAP-TLS", EAP_METHOD_TLS }, | |
1165 { "EAP-TTLS", EAP_METHOD_TTLS }, | |
1166 { "LEAP", EAP_METHOD_LEAP }, | |
1167 }; | |
1168 CR_DEFINE_STATIC_LOCAL(EnumMapper<EAPMethod>, parser, | |
1169 (table, arraysize(table), EAP_METHOD_UNKNOWN)); | |
1170 return parser.Get(method); | |
1171 } | |
1172 | |
1173 // static | |
1174 EAPPhase2Auth OncWifiNetworkParser::ParseEAPPhase2Auth( | |
1175 const std::string& auth) { | |
1176 static EnumMapper<EAPPhase2Auth>::Pair table[] = { | |
1177 { "MD5", EAP_PHASE_2_AUTH_MD5 }, | |
1178 { "MSCHAPV2", EAP_PHASE_2_AUTH_MSCHAPV2 }, | |
1179 { "MSCHAP", EAP_PHASE_2_AUTH_MSCHAP }, | |
1180 { "PAP", EAP_PHASE_2_AUTH_PAP }, | |
1181 }; | |
1182 CR_DEFINE_STATIC_LOCAL(EnumMapper<EAPPhase2Auth>, parser, | |
1183 (table, arraysize(table), EAP_PHASE_2_AUTH_AUTO)); | |
1184 return parser.Get(auth); | |
1185 } | |
1186 | |
1187 // -------------------- OncVirtualNetworkParser -------------------- | |
1188 | |
1189 | |
1190 OncVirtualNetworkParser::OncVirtualNetworkParser() {} | |
1191 OncVirtualNetworkParser::~OncVirtualNetworkParser() {} | |
1192 | |
1193 bool OncVirtualNetworkParser::UpdateNetworkFromInfo( | |
1194 const DictionaryValue& info, | |
1195 Network* network) { | |
1196 DCHECK_EQ(TYPE_VPN, network->type()); | |
1197 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); | |
1198 if (!OncNetworkParser::UpdateNetworkFromInfo(info, network)) | |
1199 return false; | |
1200 VLOG(1) << "Updating VPN '" << virtual_network->name() | |
1201 << "': Server: " << virtual_network->server_hostname() | |
1202 << " Type: " | |
1203 << ProviderTypeToString(virtual_network->provider_type()); | |
1204 return true; | |
1205 } | |
1206 | |
1207 // static | |
1208 bool OncVirtualNetworkParser::ParseVPNValue(OncNetworkParser* parser, | |
1209 PropertyIndex index, | |
1210 const base::Value& value, | |
1211 Network* network) { | |
1212 if (!CheckNetworkType(network, TYPE_VPN, onc::kVPN)) | |
1213 return false; | |
1214 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); | |
1215 switch (index) { | |
1216 case PROPERTY_INDEX_PROVIDER_HOST: { | |
1217 base::StringValue empty_value(""); | |
1218 virtual_network->set_server_hostname(GetStringValue(value)); | |
1219 // Shill requires a domain property which is unused. | |
1220 network->UpdatePropertyMap(PROPERTY_INDEX_VPN_DOMAIN, &empty_value); | |
1221 return true; | |
1222 } | |
1223 case PROPERTY_INDEX_ONC_IPSEC: | |
1224 if (virtual_network->provider_type() != PROVIDER_TYPE_L2TP_IPSEC_PSK && | |
1225 virtual_network->provider_type() != | |
1226 PROVIDER_TYPE_L2TP_IPSEC_USER_CERT) { | |
1227 VLOG(1) << "IPsec field not allowed with this VPN type"; | |
1228 return false; | |
1229 } | |
1230 return parser->ParseNestedObject(network, | |
1231 onc::vpn::kIPsec, | |
1232 value, | |
1233 ipsec_signature, | |
1234 ParseIPsecValue); | |
1235 case PROPERTY_INDEX_ONC_L2TP: | |
1236 if (virtual_network->provider_type() != PROVIDER_TYPE_L2TP_IPSEC_PSK) { | |
1237 VLOG(1) << "L2TP field not allowed with this VPN type"; | |
1238 return false; | |
1239 } | |
1240 return parser->ParseNestedObject(network, | |
1241 onc::vpn::kL2TP, | |
1242 value, | |
1243 l2tp_signature, | |
1244 ParseL2TPValue); | |
1245 case PROPERTY_INDEX_ONC_OPENVPN: { | |
1246 if (virtual_network->provider_type() != PROVIDER_TYPE_OPEN_VPN) { | |
1247 VLOG(1) << "OpenVPN field not allowed with this VPN type"; | |
1248 return false; | |
1249 } | |
1250 // The following are needed by shill to set up the OpenVPN | |
1251 // management channel which every ONC OpenVPN configuration will | |
1252 // use. | |
1253 base::StringValue empty_value(""); | |
1254 network->UpdatePropertyMap(PROPERTY_INDEX_OPEN_VPN_AUTHUSERPASS, | |
1255 &empty_value); | |
1256 network->UpdatePropertyMap(PROPERTY_INDEX_OPEN_VPN_MGMT_ENABLE, | |
1257 &empty_value); | |
1258 return parser->ParseNestedObject(network, | |
1259 onc::vpn::kOpenVPN, | |
1260 value, | |
1261 openvpn_signature, | |
1262 ParseOpenVPNValue); | |
1263 } | |
1264 case PROPERTY_INDEX_PROVIDER_TYPE: { | |
1265 // Update property with native value for provider type. | |
1266 ProviderType provider_type = GetCanonicalProviderType( | |
1267 virtual_network->provider_type()); | |
1268 std::string str = | |
1269 NativeVirtualNetworkParser::provider_type_mapper()->GetKey( | |
1270 provider_type); | |
1271 base::StringValue val(str); | |
1272 network->UpdatePropertyMap(PROPERTY_INDEX_PROVIDER_TYPE, &val); | |
1273 return true; | |
1274 } | |
1275 default: | |
1276 break; | |
1277 } | |
1278 return false; | |
1279 } | |
1280 | |
1281 bool OncVirtualNetworkParser::ParseIPsecValue(OncNetworkParser* parser, | |
1282 PropertyIndex index, | |
1283 const base::Value& value, | |
1284 Network* network) { | |
1285 if (!CheckNetworkType(network, TYPE_VPN, onc::vpn::kIPsec)) | |
1286 return false; | |
1287 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); | |
1288 switch (index) { | |
1289 case PROPERTY_INDEX_IPSEC_AUTHENTICATIONTYPE: | |
1290 virtual_network->set_provider_type( | |
1291 UpdateProviderTypeWithAuthType(virtual_network->provider_type(), | |
1292 GetStringValue(value))); | |
1293 return true; | |
1294 case PROPERTY_INDEX_L2TPIPSEC_CA_CERT_NSS: | |
1295 virtual_network->set_ca_cert_nss(GetStringValue(value)); | |
1296 return true; | |
1297 case PROPERTY_INDEX_L2TPIPSEC_PSK: | |
1298 virtual_network->set_psk_passphrase(GetStringValue(value)); | |
1299 return true; | |
1300 case PROPERTY_INDEX_L2TPIPSEC_GROUP_NAME: | |
1301 virtual_network->set_group_name(GetStringValue(value)); | |
1302 return true; | |
1303 case PROPERTY_INDEX_SAVE_CREDENTIALS: | |
1304 // Note that the specification allows different settings for | |
1305 // IPsec credentials (PSK) and L2TP credentials (username and | |
1306 // password) but we merge them in our implementation as is required | |
1307 // with the current connection manager. | |
1308 virtual_network->set_save_credentials(GetBooleanValue(value)); | |
1309 return true; | |
1310 case PROPERTY_INDEX_ONC_CLIENT_CERT_REF: { | |
1311 std::string cert_id = GetPkcs11IdFromCertGuid(GetStringValue(value)); | |
1312 if (cert_id.empty()) | |
1313 return false; | |
1314 virtual_network->set_client_cert_id(cert_id); | |
1315 return true; | |
1316 } | |
1317 case PROPERTY_INDEX_ONC_CLIENT_CERT_PATTERN: { | |
1318 return parser->ParseNestedObject(virtual_network, | |
1319 onc::vpn::kClientCertPattern, | |
1320 value, | |
1321 certificate_pattern_signature, | |
1322 ParseClientCertPattern); | |
1323 } | |
1324 case PROPERTY_INDEX_ONC_CLIENT_CERT_TYPE: { | |
1325 ClientCertType type = ParseClientCertType(GetStringValue(value)); | |
1326 virtual_network->set_client_cert_type(type); | |
1327 return true; | |
1328 } | |
1329 case PROPERTY_INDEX_IPSEC_IKEVERSION: { | |
1330 if (!value.IsType(TYPE_STRING)) { | |
1331 // Shill wants all provider properties to be strings. | |
1332 base::StringValue string_value(ConvertValueToString(value)); | |
1333 virtual_network->UpdatePropertyMap(index, &string_value); | |
1334 } | |
1335 return true; | |
1336 } | |
1337 default: | |
1338 break; | |
1339 } | |
1340 return false; | |
1341 } | |
1342 | |
1343 // static | |
1344 ProviderType OncVirtualNetworkParser::UpdateProviderTypeWithAuthType( | |
1345 ProviderType provider, | |
1346 const std::string& auth_type) { | |
1347 switch (provider) { | |
1348 case PROVIDER_TYPE_L2TP_IPSEC_PSK: | |
1349 case PROVIDER_TYPE_L2TP_IPSEC_USER_CERT: | |
1350 if (auth_type == "Cert") { | |
1351 return PROVIDER_TYPE_L2TP_IPSEC_USER_CERT; | |
1352 } else { | |
1353 if (auth_type != "PSK") { | |
1354 VLOG(1) << "Unexpected authentication type " << auth_type; | |
1355 break; | |
1356 } | |
1357 return PROVIDER_TYPE_L2TP_IPSEC_PSK; | |
1358 } | |
1359 default: | |
1360 VLOG(1) << "Unexpected provider type with authentication type " | |
1361 << auth_type; | |
1362 break; | |
1363 } | |
1364 return provider; | |
1365 } | |
1366 | |
1367 // static | |
1368 ProviderType OncVirtualNetworkParser::GetCanonicalProviderType( | |
1369 ProviderType provider_type) { | |
1370 if (provider_type == PROVIDER_TYPE_L2TP_IPSEC_USER_CERT) | |
1371 return PROVIDER_TYPE_L2TP_IPSEC_PSK; | |
1372 return provider_type; | |
1373 } | |
1374 | |
1375 // static | |
1376 bool OncVirtualNetworkParser::ParseL2TPValue(OncNetworkParser* parser, | |
1377 PropertyIndex index, | |
1378 const base::Value& value, | |
1379 Network* network) { | |
1380 if (!CheckNetworkType(network, TYPE_VPN, "L2TP")) | |
1381 return false; | |
1382 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); | |
1383 switch (index) { | |
1384 case PROPERTY_INDEX_L2TPIPSEC_PASSWORD: | |
1385 virtual_network->set_user_passphrase(GetStringValue(value)); | |
1386 return true; | |
1387 case PROPERTY_INDEX_L2TPIPSEC_USER: { | |
1388 const std::string expanded_user( | |
1389 GetUserExpandedValue(value, parser->onc_source())); | |
1390 virtual_network->set_username(expanded_user); | |
1391 const StringValue expanded_user_value(expanded_user); | |
1392 virtual_network->UpdatePropertyMap(index, &expanded_user_value); | |
1393 return true; | |
1394 } | |
1395 case PROPERTY_INDEX_SAVE_CREDENTIALS: | |
1396 // Note that the specification allows different settings for | |
1397 // IPsec credentials (PSK) and L2TP credentials (username and | |
1398 // password) but we merge them in our implementation as is required | |
1399 // with the current connection manager. | |
1400 virtual_network->set_save_credentials(GetBooleanValue(value)); | |
1401 return true; | |
1402 default: | |
1403 break; | |
1404 } | |
1405 return false; | |
1406 } | |
1407 | |
1408 // static | |
1409 bool OncVirtualNetworkParser::ParseOpenVPNValue(OncNetworkParser* parser, | |
1410 PropertyIndex index, | |
1411 const base::Value& value, | |
1412 Network* network) { | |
1413 if (!CheckNetworkType(network, TYPE_VPN, "OpenVPN")) | |
1414 return false; | |
1415 VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); | |
1416 switch (index) { | |
1417 case PROPERTY_INDEX_OPEN_VPN_PASSWORD: | |
1418 virtual_network->set_user_passphrase(GetStringValue(value)); | |
1419 return true; | |
1420 case PROPERTY_INDEX_OPEN_VPN_USER: { | |
1421 const std::string expanded_user( | |
1422 GetUserExpandedValue(value, parser->onc_source())); | |
1423 virtual_network->set_username(expanded_user); | |
1424 const StringValue expanded_user_value(expanded_user); | |
1425 virtual_network->UpdatePropertyMap(index, &expanded_user_value); | |
1426 return true; | |
1427 } | |
1428 case PROPERTY_INDEX_SAVE_CREDENTIALS: | |
1429 virtual_network->set_save_credentials(GetBooleanValue(value)); | |
1430 return true; | |
1431 case PROPERTY_INDEX_OPEN_VPN_CACERT: | |
1432 virtual_network->set_ca_cert_nss(GetStringValue(value)); | |
1433 return true; | |
1434 case PROPERTY_INDEX_OPEN_VPN_REMOTECERTKU: { | |
1435 // ONC supports a list of these, but we shill supports only one | |
1436 // today. So extract the first. | |
1437 const base::ListValue* value_list = NULL; | |
1438 value.GetAsList(&value_list); | |
1439 const base::Value* first_item = NULL; | |
1440 if (!value_list->Get(0, &first_item) || | |
1441 !first_item->IsType(base::Value::TYPE_STRING)) { | |
1442 VLOG(1) << "RemoteCertKU must be non-empty list of strings"; | |
1443 return false; | |
1444 } | |
1445 virtual_network->UpdatePropertyMap(index, first_item); | |
1446 return true; | |
1447 } | |
1448 case PROPERTY_INDEX_OPEN_VPN_AUTH: | |
1449 case PROPERTY_INDEX_OPEN_VPN_AUTHRETRY: | |
1450 case PROPERTY_INDEX_OPEN_VPN_AUTHNOCACHE: | |
1451 case PROPERTY_INDEX_OPEN_VPN_CERT: | |
1452 case PROPERTY_INDEX_OPEN_VPN_CIPHER: | |
1453 case PROPERTY_INDEX_OPEN_VPN_COMPLZO: | |
1454 case PROPERTY_INDEX_OPEN_VPN_COMPNOADAPT: | |
1455 case PROPERTY_INDEX_OPEN_VPN_KEYDIRECTION: | |
1456 case PROPERTY_INDEX_OPEN_VPN_NSCERTTYPE: | |
1457 case PROPERTY_INDEX_OPEN_VPN_PORT: | |
1458 case PROPERTY_INDEX_OPEN_VPN_PROTO: | |
1459 case PROPERTY_INDEX_OPEN_VPN_PUSHPEERINFO: | |
1460 case PROPERTY_INDEX_OPEN_VPN_REMOTECERTEKU: | |
1461 case PROPERTY_INDEX_OPEN_VPN_REMOTECERTTLS: | |
1462 case PROPERTY_INDEX_OPEN_VPN_RENEGSEC: | |
1463 case PROPERTY_INDEX_OPEN_VPN_SERVERPOLLTIMEOUT: | |
1464 case PROPERTY_INDEX_OPEN_VPN_SHAPER: | |
1465 case PROPERTY_INDEX_OPEN_VPN_STATICCHALLENGE: | |
1466 case PROPERTY_INDEX_OPEN_VPN_TLSAUTHCONTENTS: | |
1467 case PROPERTY_INDEX_OPEN_VPN_TLSREMOTE: { | |
1468 if (!value.IsType(TYPE_STRING)) { | |
1469 // Shill wants all provider properties to be strings. | |
1470 base::StringValue string_value(ConvertValueToString(value)); | |
1471 virtual_network->UpdatePropertyMap(index, &string_value); | |
1472 } | |
1473 return true; | |
1474 } | |
1475 case PROPERTY_INDEX_ONC_CLIENT_CERT_REF: { | |
1476 std::string cert_id = GetPkcs11IdFromCertGuid(GetStringValue(value)); | |
1477 if (cert_id.empty()) | |
1478 return false; | |
1479 virtual_network->set_client_cert_id(cert_id); | |
1480 return true; | |
1481 } | |
1482 case PROPERTY_INDEX_ONC_CLIENT_CERT_PATTERN: | |
1483 return parser->ParseNestedObject( | |
1484 virtual_network, | |
1485 onc::eap::kClientCertPattern, | |
1486 value, | |
1487 certificate_pattern_signature, | |
1488 OncNetworkParser::ParseClientCertPattern); | |
1489 case PROPERTY_INDEX_ONC_CLIENT_CERT_TYPE: { | |
1490 ClientCertType type = ParseClientCertType(GetStringValue(value)); | |
1491 virtual_network->set_client_cert_type(type); | |
1492 return true; | |
1493 } | |
1494 | |
1495 default: | |
1496 break; | |
1497 } | |
1498 return false; | |
1499 } | |
1500 | |
1501 // static | |
1502 ProviderType OncVirtualNetworkParser::ParseProviderType( | |
1503 const std::string& type) { | |
1504 static EnumMapper<ProviderType>::Pair table[] = { | |
1505 // We initially map to L2TP-IPsec PSK and then fix this up based | |
1506 // on the value of AuthenticationType. | |
1507 { "L2TP-IPsec", PROVIDER_TYPE_L2TP_IPSEC_PSK }, | |
1508 { "OpenVPN", PROVIDER_TYPE_OPEN_VPN }, | |
1509 }; | |
1510 CR_DEFINE_STATIC_LOCAL(EnumMapper<ProviderType>, parser, | |
1511 (table, arraysize(table), PROVIDER_TYPE_MAX)); | |
1512 return parser.Get(type); | |
1513 } | |
1514 | |
1515 } // namespace chromeos | |
OLD | NEW |