Index: chrome/browser/chromeos/cros/onc_network_parser.cc |
=================================================================== |
--- chrome/browser/chromeos/cros/onc_network_parser.cc (revision 112277) |
+++ chrome/browser/chromeos/cros/onc_network_parser.cc (working copy) |
@@ -22,34 +22,114 @@ |
// Local constants. |
namespace { |
-EnumMapper<PropertyIndex>::Pair property_index_table[] = { |
- { "GUID", PROPERTY_INDEX_GUID }, |
- { "Name", PROPERTY_INDEX_NAME }, |
- { "Remove", PROPERTY_INDEX_REMOVE }, |
- { "ProxyURL", PROPERTY_INDEX_PROXY_CONFIG }, |
- { "Type", PROPERTY_INDEX_TYPE }, |
- { "SSID", PROPERTY_INDEX_SSID }, |
- { "Passphrase", PROPERTY_INDEX_PASSPHRASE }, |
- { "AutoConnect", PROPERTY_INDEX_AUTO_CONNECT }, |
- { "HiddenSSID", PROPERTY_INDEX_HIDDEN_SSID }, |
- { "Security", PROPERTY_INDEX_SECURITY }, |
- { "EAP", PROPERTY_INDEX_EAP }, |
- { "Outer", PROPERTY_INDEX_EAP_METHOD }, |
- { "Inner", PROPERTY_INDEX_EAP_PHASE_2_AUTH }, |
- { "UseSystemCAs", PROPERTY_INDEX_EAP_USE_SYSTEM_CAS }, |
- { "ServerCARef", PROPERTY_INDEX_EAP_CA_CERT }, |
- { "ClientCARef", PROPERTY_INDEX_EAP_CLIENT_CERT }, |
- { "ClientCertPattern", PROPERTY_INDEX_EAP_CLIENT_CERT_PATTERN }, |
- { "Identity", PROPERTY_INDEX_EAP_IDENTITY }, |
- { "Password", PROPERTY_INDEX_EAP_PASSWORD }, |
- { "AnonymousIdentity", PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY }, |
+EnumMapper<PropertyIndex>::Pair network_configuration_table[] = { |
+ { "GUID", PROPERTY_INDEX_GUID }, |
+ { "Name", PROPERTY_INDEX_NAME }, |
+ { "Remove", PROPERTY_INDEX_ONC_REMOVE }, |
+ { "Type", PROPERTY_INDEX_TYPE }, |
+ { "WiFi", PROPERTY_INDEX_ONC_WIFI }, |
+ { "VPN", PROPERTY_INDEX_ONC_VPN } |
}; |
+const base::Value::Type TYPE_BOOLEAN = base::Value::TYPE_BOOLEAN; |
Mattias Nissler (ping if slow)
2011/12/01 13:09:10
why not just:
using base::Value::TYPE_BOOLEAN;
kmixter1
2011/12/01 19:48:41
using doesn't work with things inside of classes.
|
+const base::Value::Type TYPE_DICTIONARY = base::Value::TYPE_DICTIONARY; |
+const base::Value::Type TYPE_INTEGER = base::Value::TYPE_INTEGER; |
+const base::Value::Type TYPE_LIST = base::Value::TYPE_LIST; |
+const base::Value::Type TYPE_STRING = base::Value::TYPE_STRING; |
+ |
+OncValueSignature wifi_signature[] = { |
+ { "AutoConnect", PROPERTY_INDEX_AUTO_CONNECT, TYPE_STRING }, |
+ { "EAP", PROPERTY_INDEX_EAP, TYPE_DICTIONARY }, |
+ { "HiddenSSID", PROPERTY_INDEX_HIDDEN_SSID, TYPE_BOOLEAN }, |
+ { "Passphrase", PROPERTY_INDEX_PASSPHRASE, TYPE_STRING }, |
+ { "ProxyURL", PROPERTY_INDEX_PROXY_CONFIG, TYPE_STRING }, |
+ { "Security", PROPERTY_INDEX_SECURITY, TYPE_STRING }, |
+ { "SSID", PROPERTY_INDEX_SSID, TYPE_STRING }, |
+ { NULL } |
+}; |
+ |
+OncValueSignature eap_signature[] = { |
+ { "AnonymousIdentity", PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY, TYPE_STRING }, |
+ { "ClientCARef", PROPERTY_INDEX_EAP_CLIENT_CERT, TYPE_STRING }, |
+ { "ClientCertPattern", PROPERTY_INDEX_EAP_CLIENT_CERT_PATTERN, TYPE_STRING }, |
+ { "Identity", PROPERTY_INDEX_EAP_IDENTITY, TYPE_STRING }, |
+ { "Inner", PROPERTY_INDEX_EAP_PHASE_2_AUTH, TYPE_STRING }, |
+ { "Outer", PROPERTY_INDEX_EAP_METHOD, TYPE_STRING }, |
+ { "Password", PROPERTY_INDEX_EAP_PASSWORD, TYPE_STRING }, |
+ { "ServerCARef", PROPERTY_INDEX_EAP_CA_CERT, TYPE_STRING }, |
+ { "UseSystemCAs", PROPERTY_INDEX_EAP_USE_SYSTEM_CAS, TYPE_BOOLEAN }, |
+ { NULL } |
+}; |
+ |
+OncValueSignature vpn_signature[] = { |
+ { "Host", PROPERTY_INDEX_HOST, TYPE_STRING }, |
+ { "IPsec", PROPERTY_INDEX_ONC_IPSEC, TYPE_DICTIONARY }, |
+ { "L2TP", PROPERTY_INDEX_ONC_L2TP, TYPE_DICTIONARY }, |
+ { "OpenVPN", PROPERTY_INDEX_ONC_OPENVPN, TYPE_DICTIONARY }, |
+ { "Type", PROPERTY_INDEX_PROVIDER_TYPE, TYPE_STRING }, |
+ { NULL } |
+}; |
+ |
+OncValueSignature ipsec_signature[] = { |
+ { "AuthenticationType", PROPERTY_INDEX_IPSEC_AUTHENTICATIONTYPE, |
+ TYPE_STRING }, |
+ { "Group", PROPERTY_INDEX_L2TPIPSEC_GROUP_NAME, TYPE_STRING }, |
+ { "IKEVersion", PROPERTY_INDEX_IPSEC_IKEVERSION, TYPE_INTEGER }, |
+ // Note: ClientCertRef, ClientCertPattern, ClientCertType are |
+ // purposefully avoided. |
+ // Note: EAP and XAUTH not yet supported. |
+ { "PSK", PROPERTY_INDEX_L2TPIPSEC_PSK, TYPE_STRING }, |
+ { "SaveCredentials", PROPERTY_INDEX_SAVE_CREDENTIALS, TYPE_BOOLEAN }, |
+ { "ServerCARef", PROPERTY_INDEX_L2TPIPSEC_CA_CERT_NSS, TYPE_STRING }, |
+ { NULL } |
+}; |
+ |
+OncValueSignature l2tp_signature[] = { |
+ { "Password", PROPERTY_INDEX_L2TPIPSEC_PASSWORD, TYPE_STRING }, |
+ { "SaveCredentials", PROPERTY_INDEX_SAVE_CREDENTIALS, TYPE_BOOLEAN }, |
+ { "Username", PROPERTY_INDEX_L2TPIPSEC_USER, TYPE_STRING }, |
+ { NULL } |
+}; |
+ |
+OncValueSignature openvpn_signature[] = { |
+ { "Auth", PROPERTY_INDEX_OPEN_VPN_AUTH, TYPE_STRING }, |
+ { "AuthRetry", PROPERTY_INDEX_OPEN_VPN_AUTHRETRY, TYPE_STRING }, |
+ { "AuthNoCache", PROPERTY_INDEX_OPEN_VPN_AUTHNOCACHE, TYPE_BOOLEAN }, |
+ { "Cipher", PROPERTY_INDEX_OPEN_VPN_CIPHER, TYPE_STRING }, |
+ // Note: ClientCertRef, ClientCertPattern, ClientCertType are |
+ // purposefully avoided. |
+ { "CompLZO", PROPERTY_INDEX_OPEN_VPN_COMPLZO, TYPE_STRING }, |
+ { "CompNoAdapt", PROPERTY_INDEX_OPEN_VPN_COMPNOADAPT, TYPE_BOOLEAN }, |
+ { "KeyDirection", PROPERTY_INDEX_OPEN_VPN_KEYDIRECTION, TYPE_STRING }, |
+ { "NsCertType", PROPERTY_INDEX_OPEN_VPN_NSCERTTYPE, TYPE_STRING }, |
+ { "Password", PROPERTY_INDEX_OPEN_VPN_PASSWORD, TYPE_STRING }, |
+ { "Port", PROPERTY_INDEX_OPEN_VPN_PORT, TYPE_INTEGER }, |
+ { "Proto", PROPERTY_INDEX_OPEN_VPN_PROTO, TYPE_STRING }, |
+ { "PushPeerInfo", PROPERTY_INDEX_OPEN_VPN_PUSHPEERINFO, TYPE_BOOLEAN }, |
+ { "RemoteCertEKU", PROPERTY_INDEX_OPEN_VPN_REMOTECERTEKU, TYPE_STRING }, |
+ // TODO(kmixter): Extract just the first item from this list before |
+ // sending it down. |
+ { "RemoteCertKU", PROPERTY_INDEX_OPEN_VPN_REMOTECERTKU, TYPE_LIST }, |
+ { "RemoteCertTLS", PROPERTY_INDEX_OPEN_VPN_REMOTECERTTLS, TYPE_STRING }, |
+ { "RenegSec", PROPERTY_INDEX_OPEN_VPN_RENEGSEC, TYPE_INTEGER }, |
+ { "SaveCredentials", PROPERTY_INDEX_SAVE_CREDENTIALS, TYPE_BOOLEAN }, |
+ { "ServerCARef", PROPERTY_INDEX_OPEN_VPN_CACERT, TYPE_STRING }, |
+ { "ServerCertRef", PROPERTY_INDEX_OPEN_VPN_CERT, TYPE_STRING }, |
+ { "ServerPollTimeout", PROPERTY_INDEX_OPEN_VPN_SERVERPOLLTIMEOUT, |
+ TYPE_INTEGER }, |
+ { "Shaper", PROPERTY_INDEX_OPEN_VPN_SHAPER, TYPE_INTEGER }, |
+ { "StaticChallenge", PROPERTY_INDEX_OPEN_VPN_STATICCHALLENGE, TYPE_STRING }, |
+ { "TLSAuthContents", PROPERTY_INDEX_OPEN_VPN_TLSAUTHCONTENTS, TYPE_STRING }, |
+ { "TLSRemote", PROPERTY_INDEX_OPEN_VPN_TLSREMOTE, TYPE_STRING }, |
+ { "Username", PROPERTY_INDEX_OPEN_VPN_USER, TYPE_STRING }, |
+ { NULL } |
+}; |
+ |
// Serve the singleton mapper instance. |
const EnumMapper<PropertyIndex>* get_onc_mapper() { |
CR_DEFINE_STATIC_LOCAL(const EnumMapper<PropertyIndex>, mapper, |
- (property_index_table, |
- arraysize(property_index_table), |
+ (network_configuration_table, |
+ arraysize(network_configuration_table), |
PROPERTY_INDEX_UNKNOWN)); |
return &mapper; |
} |
@@ -156,6 +236,7 @@ |
if (!network_configs_->GetDictionary(n, &info)) |
return NULL; |
// Parse Open Network Configuration blob into a temporary Network object. |
+ // TODO(crosbug.com/23604): Handle removing networks. |
return CreateNetworkFromInfo(std::string(), *info); |
} |
@@ -171,16 +252,7 @@ |
scoped_ptr<StringValue> val(Value::CreateStringValue(str)); |
network->UpdatePropertyMap(PROPERTY_INDEX_TYPE, *val.get()); |
- // Get the child dictionary with properties for the network. |
- // And copy all the values from this network type dictionary to parent. |
- DictionaryValue* dict; |
- if (!info.GetDictionary(GetTypeFromDictionary(info), &dict)) |
- return NULL; |
- |
- // Add GUID from the parent dictionary. |
- dict->SetString("GUID", GetGuidFromDictionary(info)); |
- |
- UpdateNetworkFromInfo(*dict, network.get()); |
+ UpdateNetworkFromInfo(info, network.get()); |
VLOG(2) << "Created Network '" << network->name() |
<< "' from info. Path:" << service_path |
<< " Type:" << ConnectionTypeToString(type); |
@@ -329,6 +401,51 @@ |
return true; |
} |
+bool OncNetworkParser::ParseNestedObject(Network* network, |
+ const std::string& onc_type, |
+ const base::Value& value, |
+ OncValueSignature* signature, |
+ ParserPointer parser) { |
+ bool any_errors = false; |
+ if (value.GetType() != Value::TYPE_DICTIONARY) { |
Mattias Nissler (ping if slow)
2011/12/01 13:09:10
Shortcut: value.IsType(base::Value::TYPE_DICTIONAR
Mattias Nissler (ping if slow)
2011/12/01 13:09:10
also, Value is in namespace base nowadays, so you
kmixter1
2011/12/01 19:48:41
Done.
kmixter1
2011/12/01 19:48:41
Added the prefix to be exact but somewhere else it
|
+ VLOG(1) << network->name() << ": expected object of type " << onc_type; |
+ return false; |
+ } |
+ const DictionaryValue& dict = static_cast<const DictionaryValue&>(value); |
+ for (DictionaryValue::key_iterator iter = dict.begin_keys(); |
+ iter != dict.end_keys(); ++iter) { |
+ const std::string& key = *iter; |
+ base::Value* inner_value; |
+ bool res = dict.GetWithoutPathExpansion(key, &inner_value); |
+ if (!res) { |
+ DCHECK(res); |
Mattias Nissler (ping if slow)
2011/12/01 13:09:10
I'd just remove the if and make this a CHECK(). If
Charlie Lee
2011/12/01 18:53:18
Probably don't even need a CHECK(). If it ever fai
kmixter1
2011/12/01 19:48:41
Done.
kmixter1
2011/12/01 19:48:41
Done.
|
+ continue; |
+ } |
+ PropertyIndex index = PROPERTY_INDEX_UNKNOWN; |
+ int field; |
Charlie Lee
2011/12/01 18:53:18
should probably name this something other than fie
kmixter1
2011/12/01 19:48:41
Done.
|
+ for (field = 0; signature[field].field != NULL; ++field) { |
Charlie Lee
2011/12/01 18:53:18
consider using a map instead of an array so it's m
kmixter1
2011/12/01 19:48:41
Yeah, I suspect what we'll want to do is construct
|
+ if (key == signature[field].field) break; |
Mattias Nissler (ping if slow)
2011/12/01 13:09:10
I actually missed that break and were going to com
kmixter1
2011/12/01 19:48:41
Done.
|
+ } |
+ if (signature[field].field != NULL) { |
+ if (inner_value->GetType() != signature[field].type) { |
+ VLOG(1) << network->name() << ": " << onc_type |
+ << " unhandled field: " << key << " Type: " |
+ << inner_value->GetType(); |
+ } else { |
+ if (parser(this, index, *inner_value, network)) { |
+ continue; |
+ } |
+ } |
+ } |
Mattias Nissler (ping if slow)
2011/12/01 13:09:10
I think you can just collapse these nested conditi
kmixter1
2011/12/01 19:48:41
I preferred to give more specific error messages f
|
+ network->UpdatePropertyMap(index, *inner_value); |
Mattias Nissler (ping if slow)
2011/12/01 13:09:10
Do we really want to update the map for unrecogniz
kmixter1
2011/12/01 19:48:41
No, but we do need to update it before we run the
|
+ VLOG(1) << network->name() << ": " << onc_type |
+ << " unhandled field: " << key << " Type: " |
+ << inner_value->GetType(); |
+ any_errors = true; |
+ } |
+ return !any_errors; |
+} |
+ |
// -------------------- OncWirelessNetworkParser -------------------- |
OncWirelessNetworkParser::OncWirelessNetworkParser() {} |
@@ -344,7 +461,9 @@ |
// -------------------- OncWifiNetworkParser -------------------- |
-OncWifiNetworkParser::OncWifiNetworkParser() {} |
+OncWifiNetworkParser::OncWifiNetworkParser() { |
Charlie Lee
2011/12/01 18:53:18
nit: probably unnecessary
kmixter1
2011/12/01 19:48:41
Done.
|
+} |
+ |
OncWifiNetworkParser::~OncWifiNetworkParser() {} |
bool OncWifiNetworkParser::ParseValue(PropertyIndex index, |
@@ -353,25 +472,33 @@ |
DCHECK_EQ(TYPE_WIFI, network->type()); |
WifiNetwork* wifi_network = static_cast<WifiNetwork*>(network); |
switch (index) { |
- case PROPERTY_INDEX_SSID: { |
- std::string ssid; |
- if (!value.GetAsString(&ssid)) |
- break; |
- wifi_network->SetName(ssid); |
+ case PROPERTY_INDEX_ONC_WIFI: { |
+ // TODO(kmixter): Purposefully ignore return value? |
+ ParseNestedObject(wifi_network, "WiFi", value, |
+ wifi_signature, ParseWifiValue); |
return true; |
} |
+ default: |
+ return OncNetworkParser::ParseValue(index, value, network); |
+ } |
+} |
+ |
+bool OncWifiNetworkParser::ParseWifiValue(OncNetworkParser* parser, |
+ PropertyIndex index, |
+ const base::Value& value, |
+ Network* network) { |
+ WifiNetwork* wifi_network = static_cast<WifiNetwork*>(network); |
+ std::string string_value; |
+ value.GetAsString(&string_value); |
+ switch (index) { |
+ case PROPERTY_INDEX_SSID: |
+ wifi_network->SetName(string_value); |
+ return true; |
case PROPERTY_INDEX_GUID: { |
- std::string unique_id; |
- if (!value.GetAsString(&unique_id)) |
- break; |
- wifi_network->set_unique_id(unique_id); |
+ wifi_network->set_unique_id(string_value); |
return true; |
- } |
case PROPERTY_INDEX_SECURITY: { |
- std::string security_string; |
- if (!value.GetAsString(&security_string)) |
- break; |
- ConnectionSecurity security = ParseSecurity(security_string); |
+ ConnectionSecurity security = ParseSecurity(string_value); |
wifi_network->set_encryption(security); |
// Also update property with native value for security. |
std::string str = |
@@ -380,62 +507,49 @@ |
wifi_network->UpdatePropertyMap(index, *val.get()); |
return true; |
} |
- case PROPERTY_INDEX_PASSPHRASE: { |
- std::string passphrase; |
- if (!value.GetAsString(&passphrase)) |
- break; |
- wifi_network->set_passphrase(passphrase); |
+ case PROPERTY_INDEX_PASSPHRASE: |
+ wifi_network->set_passphrase(string_value); |
return true; |
- } |
- case PROPERTY_INDEX_IDENTITY: { |
- std::string identity; |
- if (!value.GetAsString(&identity)) |
- break; |
- wifi_network->set_identity(identity); |
+ case PROPERTY_INDEX_IDENTITY: |
+ wifi_network->set_identity(string_value); |
return true; |
- } |
- case PROPERTY_INDEX_EAP: { |
- DCHECK_EQ(value.GetType(), Value::TYPE_DICTIONARY); |
- const DictionaryValue& dict = static_cast<const DictionaryValue&>(value); |
- for (DictionaryValue::key_iterator iter = dict.begin_keys(); |
- iter != dict.end_keys(); ++iter) { |
- const std::string& key = *iter; |
- base::Value* eap_value; |
- bool res = dict.GetWithoutPathExpansion(key, &eap_value); |
- DCHECK(res); |
- if (res) { |
- PropertyIndex index = mapper().Get(key); |
- wifi_network->UpdatePropertyMap(index, *eap_value); |
- if (!ParseEAPValue(index, *eap_value, wifi_network)) |
- VLOG(1) << network->name() << ": EAP unhandled key: " << key |
- << " Type: " << eap_value->GetType(); |
- } |
- } |
+ case PROPERTY_INDEX_EAP: |
+ parser->ParseNestedObject(wifi_network, |
+ "EAP", |
+ value, |
+ eap_signature, |
+ ParseEAPValue); |
return true; |
- } |
+ |
+ case PROPERTY_INDEX_AUTO_CONNECT: |
+ case PROPERTY_INDEX_HIDDEN_SSID: |
+ // Pass these through to connection manager as is. |
+ return true; |
+ |
default: |
- return OncWirelessNetworkParser::ParseValue(index, value, network); |
+ break; |
} |
return false; |
} |
-bool OncWifiNetworkParser::ParseEAPValue(PropertyIndex index, |
+bool OncWifiNetworkParser::ParseEAPValue(OncNetworkParser*, |
+ PropertyIndex index, |
const base::Value& value, |
- WifiNetwork* wifi_network) { |
+ Network* network) { |
+ WifiNetwork* wifi_network = static_cast<WifiNetwork*>(network); |
+ std::string string_value; |
+ bool bool_value = false; |
+ |
+ value.GetAsString(&string_value); |
+ value.GetAsBoolean(&bool_value); |
+ |
switch (index) { |
- case PROPERTY_INDEX_EAP_IDENTITY: { |
- std::string eap_identity; |
- if (!value.GetAsString(&eap_identity)) |
- break; |
- wifi_network->set_eap_identity(eap_identity); |
+ case PROPERTY_INDEX_EAP_IDENTITY: |
+ wifi_network->set_eap_identity(string_value); |
return true; |
- } |
case PROPERTY_INDEX_EAP_METHOD: { |
- std::string eap_method_str; |
- if (!value.GetAsString(&eap_method_str)) |
- break; |
- EAPMethod eap_method = ParseEAPMethod(eap_method_str); |
+ EAPMethod eap_method = ParseEAPMethod(string_value); |
wifi_network->set_eap_method(eap_method); |
// Also update property with native value for EAP method. |
std::string str = |
@@ -445,10 +559,7 @@ |
return true; |
} |
case PROPERTY_INDEX_EAP_PHASE_2_AUTH: { |
- std::string eap_phase_2_auth_str; |
- if (!value.GetAsString(&eap_phase_2_auth_str)) |
- break; |
- EAPPhase2Auth eap_phase_2_auth = ParseEAPPhase2Auth(eap_phase_2_auth_str); |
+ EAPPhase2Auth eap_phase_2_auth = ParseEAPPhase2Auth(string_value); |
wifi_network->set_eap_phase_2_auth(eap_phase_2_auth); |
// Also update property with native value for EAP phase 2 auth. |
std::string str = NativeNetworkParser::network_eap_auth_mapper()->GetKey( |
@@ -457,42 +568,21 @@ |
wifi_network->UpdatePropertyMap(index, *val.get()); |
return true; |
} |
- case PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY: { |
- std::string eap_anonymous_identity; |
- if (!value.GetAsString(&eap_anonymous_identity)) |
- break; |
- wifi_network->set_eap_anonymous_identity(eap_anonymous_identity); |
+ case PROPERTY_INDEX_EAP_ANONYMOUS_IDENTITY: |
+ wifi_network->set_eap_anonymous_identity(string_value); |
return true; |
- } |
- case PROPERTY_INDEX_EAP_CERT_ID: { |
- std::string eap_client_cert_pkcs11_id; |
- if (!value.GetAsString(&eap_client_cert_pkcs11_id)) |
- break; |
- wifi_network->set_eap_client_cert_pkcs11_id(eap_client_cert_pkcs11_id); |
+ case PROPERTY_INDEX_EAP_CERT_ID: |
+ wifi_network->set_eap_client_cert_pkcs11_id(string_value); |
return true; |
- } |
- case PROPERTY_INDEX_EAP_CA_CERT_NSS: { |
- std::string eap_server_ca_cert_nss_nickname; |
- if (!value.GetAsString(&eap_server_ca_cert_nss_nickname)) |
- break; |
- wifi_network->set_eap_server_ca_cert_nss_nickname( |
- eap_server_ca_cert_nss_nickname); |
+ case PROPERTY_INDEX_EAP_CA_CERT_NSS: |
+ wifi_network->set_eap_server_ca_cert_nss_nickname(string_value); |
return true; |
- } |
- case PROPERTY_INDEX_EAP_USE_SYSTEM_CAS: { |
- bool eap_use_system_cas; |
- if (!value.GetAsBoolean(&eap_use_system_cas)) |
- break; |
- wifi_network->set_eap_use_system_cas(eap_use_system_cas); |
+ case PROPERTY_INDEX_EAP_USE_SYSTEM_CAS: |
+ wifi_network->set_eap_use_system_cas(bool_value); |
return true; |
- } |
- case PROPERTY_INDEX_EAP_PASSWORD: { |
- std::string eap_passphrase; |
- if (!value.GetAsString(&eap_passphrase)) |
- break; |
- wifi_network->set_eap_passphrase(eap_passphrase); |
+ case PROPERTY_INDEX_EAP_PASSWORD: |
+ wifi_network->set_eap_passphrase(string_value); |
return true; |
- } |
default: |
break; |
} |
@@ -503,9 +593,9 @@ |
const std::string& security) { |
static EnumMapper<ConnectionSecurity>::Pair table[] = { |
{ "None", SECURITY_NONE }, |
- { "WEP", SECURITY_WEP }, |
- { "WPA", SECURITY_WPA }, |
- { "WPA2", SECURITY_8021X }, |
+ { "WEP-PSK", SECURITY_WEP }, |
+ { "WPA-PSK", SECURITY_WPA }, |
+ { "WPA-EAP", SECURITY_8021X }, |
}; |
CR_DEFINE_STATIC_LOCAL(EnumMapper<ConnectionSecurity>, parser, |
(table, arraysize(table), SECURITY_UNKNOWN)); |
@@ -568,21 +658,25 @@ |
VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); |
switch (index) { |
case PROPERTY_INDEX_PROVIDER: { |
- DCHECK_EQ(value.GetType(), Value::TYPE_DICTIONARY); |
+ // Got the "VPN" field. Immediately store the VPN.Type field value |
+ // so that we can properly validate nested objects based on the type. |
+ if (value.GetType() != Value::TYPE_DICTIONARY) { |
Mattias Nissler (ping if slow)
2011/12/01 13:09:10
there's value.IsType() for this.
kmixter1
2011/12/01 19:48:41
Done.
|
+ VLOG(1) << network->name() << ": expected object of type VPN"; |
+ return false; |
+ } |
const DictionaryValue& dict = static_cast<const DictionaryValue&>(value); |
Mattias Nissler (ping if slow)
2011/12/01 13:09:10
To avoid the cast, you could replace lines 663-667
kmixter1
2011/12/01 19:48:41
Done.
|
- for (DictionaryValue::key_iterator iter = dict.begin_keys(); |
- iter != dict.end_keys(); ++iter) { |
- const std::string& key = *iter; |
- base::Value* provider_value; |
- bool res = dict.GetWithoutPathExpansion(key, &provider_value); |
- DCHECK(res); |
- if (res) { |
- PropertyIndex index = mapper().Get(key); |
- if (!ParseProviderValue(index, *provider_value, virtual_network)) |
- VLOG(1) << network->name() << ": Provider unhandled key: " << key |
- << " Type: " << provider_value->GetType(); |
- } |
+ Value *provider_type_value; |
+ dict.GetWithoutPathExpansion("Type", &provider_type_value); |
+ if (provider_type_value == NULL) { |
+ VLOG(1) << network->name() << ": VPN.Type is missing"; |
+ return false; |
} |
+ std::string provider_type_string; |
+ if (!provider_type_value->GetAsString(&provider_type_string)) |
+ break; |
Mattias Nissler (ping if slow)
2011/12/01 13:09:10
Lines 668-676 shorter:
std::string provider_type_
kmixter1
2011/12/01 19:48:41
Done.
|
+ virtual_network->set_provider_type( |
+ ParseProviderType(provider_type_string)); |
+ ParseNestedObject(network, "VPN", value, vpn_signature, ParseVPNValue); |
return true; |
} |
default: |
@@ -592,75 +686,196 @@ |
return false; |
} |
-bool OncVirtualNetworkParser::ParseProviderValue(PropertyIndex index, |
- const base::Value& value, |
- VirtualNetwork* network) { |
+bool OncVirtualNetworkParser::ParseVPNValue(OncNetworkParser* parser, |
+ PropertyIndex index, |
+ const base::Value& value, |
+ Network* network) { |
+ VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); |
+ std::string string_value; |
+ value.GetAsString(&string_value); |
switch (index) { |
- case PROPERTY_INDEX_HOST: { |
- std::string server_hostname; |
- if (!value.GetAsString(&server_hostname)) |
- break; |
- network->set_server_hostname(server_hostname); |
+ case PROPERTY_INDEX_HOST: |
+ virtual_network->set_server_hostname(string_value); |
return true; |
+ case PROPERTY_INDEX_ONC_IPSEC: { |
+ if (virtual_network->provider_type() != PROVIDER_TYPE_L2TP_IPSEC_PSK && |
+ virtual_network->provider_type() != |
+ PROVIDER_TYPE_L2TP_IPSEC_USER_CERT) { |
+ VLOG(1) << "IPsec field not allowed with this VPN type"; |
+ return false; |
+ } |
+ parser->ParseNestedObject(network, |
+ "L2TP", |
+ value, |
+ l2tp_signature, |
+ ParseL2TPValue); |
+ return true; |
} |
- case PROPERTY_INDEX_NAME: { |
- std::string name; |
- if (!value.GetAsString(&name)) |
- break; |
- network->set_name(name); |
+ case PROPERTY_INDEX_ONC_L2TP: { |
+ if (virtual_network->provider_type() != PROVIDER_TYPE_L2TP_IPSEC_PSK) { |
+ VLOG(1) << "L2TP field not allowed with this VPN type"; |
+ return false; |
+ } |
+ parser->ParseNestedObject(network, |
+ "IPsec", |
+ value, |
+ ipsec_signature, |
+ ParseIPsecValue); |
return true; |
} |
- case PROPERTY_INDEX_TYPE: { |
- std::string provider_type_string; |
- if (!value.GetAsString(&provider_type_string)) |
- break; |
- network->set_provider_type(ParseProviderType(provider_type_string)); |
+ case PROPERTY_INDEX_ONC_OPENVPN: { |
+ if (network->provider_type() != PROVIDER_TYPE_L2TP_IPSEC_PSK) { |
+ VLOG(1) << "OpenVPN field not allowed with this VPN type"; |
+ return false; |
+ } |
+ parser->ParseNestedObject(network, |
+ "OpenVPN", |
+ value, |
+ openvpn_signature, |
+ ParseOpenVPNValue); |
return true; |
} |
- case PROPERTY_INDEX_L2TPIPSEC_CA_CERT_NSS: { |
- std::string ca_cert_nss; |
- if (!value.GetAsString(&ca_cert_nss)) |
- break; |
- network->set_ca_cert_nss(ca_cert_nss); |
+ case PROPERTY_INDEX_PROVIDER_TYPE: { |
+ // This was handled when we found the VPN field. |
return true; |
} |
- case PROPERTY_INDEX_L2TPIPSEC_PSK: { |
- std::string psk_passphrase; |
- if (!value.GetAsString(&psk_passphrase)) |
+ default: |
+ break; |
+ } |
+ return false; |
+} |
+ |
+bool OncVirtualNetworkParser::ParseIPsecValue(OncWifiNetworkParser* parser, |
+ PropertyIndex index, |
+ const base::Value& value, |
+ Network* network) { |
+ VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); |
+ std::string server_hostname; |
+ bool bool_value = false; |
+ value.GetAsString(&string_value); |
+ value.GetAsBoolean(&bool_value); |
+ |
+ switch (index) { |
+ case PROPERTY_INDEX_IPSEC_AUTHENTICATIONTYPE: |
+ network->set_provider_type(UpdateProviderTypeWithAuth(network->provider(), |
+ string_value)); |
+ return true; |
+ case PROPERTY_INDEX_L2TPIPSEC_CA_CERT_NSS: |
+ network->set_ca_cert_nss(string_value); |
+ return true; |
+ case PROPERTY_INDEX_L2TPIPSEC_PSK: |
+ network->set_psk_passphrase(string_value); |
+ return true; |
+ case PROPERTY_INDEX_L2TPIPSEC_GROUP_NAME: |
+ network->set_group_name(string_value); |
+ return true; |
+ case PROPERTY_INDEX_SAVE_CREDENTIALS: |
+ // Note that the specification allows different settings for |
+ // IPsec credentials (PSK) and L2TP credentials (username and |
+ // password) but we merge them in our implementation as is required |
+ // with the current connection manager. |
+ network->set_save_credentials(bool_value); |
+ return true; |
+ } |
+ return false; |
+} |
+ |
+ProviderType OncVirtualNetworkParser::UpdateProviderTypeWithAuth( |
+ ProviderType provider, |
+ const std::string& auth_type) { |
+ switch (provider) { |
+ case PROVIDER_TYPE_L2TP_IPSEC_PSK: |
+ case PROVIDER_TYPE_L2TP_IPSEC_USER_CERT: |
+ if (auth_type == "Cert") { |
+ return PROVIDER_TYPE_L2TP_IPSEC_USER_CERT; |
+ } else { |
+ if (auth_type != "PSK") { |
+ VLOG(1) << "Unexpected authentication type " << auth_type; |
break; |
- network->set_psk_passphrase(psk_passphrase); |
- return true; |
+ } |
+ return PROVIDER_TYPE_L2TP_IPSEC_PSK; |
} |
- case PROPERTY_INDEX_L2TPIPSEC_CLIENT_CERT_ID: { |
- std::string client_cert_id; |
- if (!value.GetAsString(&client_cert_id)) |
- break; |
- network->set_client_cert_id(client_cert_id); |
+ default: |
+ VLOG(1) << "Unexpected provider type with authentication type " |
+ << auth_type; |
+ break; |
+ } |
+ return provider; |
+} |
+ |
+bool OncVirtualNetworkParser::ParseL2TPValue(OncNetworkParser*, |
+ PropertyIndex index, |
+ const base::Value& value, |
+ Network* network) { |
+ VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); |
+ std::string string_value; |
+ bool bool_value = false; |
+ value.GetAsString(&string_value); |
+ value.GetAsBoolean(&bool_value); |
+ switch (index) { |
+ case PROPERTY_INDEX_L2TPIPSEC_PASSWORD: |
+ virtual_network->set_user_passphrase(string_value); |
return true; |
- } |
case PROPERTY_INDEX_L2TPIPSEC_USER: { |
- std::string username; |
- if (!value.GetAsString(&username)) |
- break; |
- network->set_username(username); |
+ virtual_network->set_username(string_value); |
return true; |
- } |
- case PROPERTY_INDEX_L2TPIPSEC_PASSWORD: { |
- std::string user_passphrase; |
- if (!value.GetAsString(&user_passphrase)) |
- break; |
- network->set_user_passphrase(user_passphrase); |
+ case PROPERTY_INDEX_SAVE_CREDENTIALS: |
+ // Note that the specification allows different settings for |
+ // IPsec credentials (PSK) and L2TP credentials (username and |
+ // password) but we merge them in our implementation as is required |
+ // with the current connection manager. |
+ virtual_network->set_save_credentials(bool_value); |
return true; |
- } |
- case PROPERTY_INDEX_L2TPIPSEC_GROUP_NAME: { |
- std::string group_name; |
- if (!value.GetAsString(&group_name)) |
- break; |
- network->set_group_name(group_name); |
+ } |
+ return false; |
+} |
+ |
+bool OncVirtualNetworkParser::ParseOpenVPNValue(OncNetworkParser*, |
+ PropertyIndex index, |
+ const base::Value& value, |
+ Network* network) { |
+ VirtualNetwork* virtual_network = static_cast<VirtualNetwork*>(network); |
+ std::string string_value; |
+ bool bool_value = false; |
+ value.GetAsString(&string_value); |
+ value.GetAsBoolean(&bool_value); |
+ switch (index) { |
+ case PROPERTY_INDEX_OPEN_VPN_PASSWORD: |
+ virtual_network->set_user_passphrase(string_value); |
return true; |
- } |
- default: |
- break; |
+ case PROPERTY_INDEX_OPEN_VPN_USER: |
+ virtual_network->set_username(string_value); |
+ return true; |
+ case PROPERTY_INDEX_SAVE_CREDENTIALS: |
+ virtual_network->set_save_credentials(bool_value); |
+ return true; |
+ case PROPERTY_INDEX_OPEN_VPN_CACERT: |
+ virtual_network->set_ca_cert_nss(string_value); |
+ return true; |
+ |
+ case PROPERTY_INDEX_OPEN_VPN_AUTH: |
+ case PROPERTY_INDEX_OPEN_VPN_AUTHRETRY: |
+ case PROPERTY_INDEX_OPEN_VPN_AUTHNOCACHE: |
+ case PROPERTY_INDEX_OPEN_VPN_CERT: |
+ case PROPERTY_INDEX_OPEN_VPN_CIPHER: |
+ case PROPERTY_INDEX_OPEN_VPN_COMPLZO: |
+ case PROPERTY_INDEX_OPEN_VPN_COMPNOADAPT: |
+ case PROPERTY_INDEX_OPEN_VPN_KEYDIRECTION: |
+ case PROPERTY_INDEX_OPEN_VPN_NSCERTTYPE: |
+ case PROPERTY_INDEX_OPEN_VPN_PORT: |
+ case PROPERTY_INDEX_OPEN_VPN_PROTO: |
+ case PROPERTY_INDEX_OPEN_VPN_PUSHPEERINFO: |
+ case PROPERTY_INDEX_OPEN_VPN_REMOTECERTEKU: |
+ case PROPERTY_INDEX_OPEN_VPN_REMOTECERTKU: |
+ case PROPERTY_INDEX_OPEN_VPN_REMOTECERTTLS: |
+ case PROPERTY_INDEX_OPEN_VPN_RENEGSEC: |
+ case PROPERTY_INDEX_OPEN_VPN_SERVERPOLLTIMEOUT: |
+ case PROPERTY_INDEX_OPEN_VPN_SHAPER: |
+ case PROPERTY_INDEX_OPEN_VPN_STATICCHALLENGE: |
+ case PROPERTY_INDEX_OPEN_VPN_TLSAUTHCONTENTS: |
+ case PROPERTY_INDEX_OPEN_VPN_TLSREMOTE: |
+ // Pass these through to connection manager as is. |
+ return true; |
} |
return false; |
} |
@@ -668,8 +883,10 @@ |
ProviderType OncVirtualNetworkParser::ParseProviderType( |
const std::string& type) { |
static EnumMapper<ProviderType>::Pair table[] = { |
- { flimflam::kProviderL2tpIpsec, PROVIDER_TYPE_L2TP_IPSEC_PSK }, |
- { flimflam::kProviderOpenVpn, PROVIDER_TYPE_OPEN_VPN }, |
+ // We initially map to L2TP-IPsec PSK and then fix this up based |
+ // on the value of AuthenticationType. |
+ { "L2TP-IPsec", PROVIDER_TYPE_L2TP_IPSEC_PSK }, |
+ { "OpenVPN", PROVIDER_TYPE_OPEN_VPN }, |
}; |
CR_DEFINE_STATIC_LOCAL(EnumMapper<ProviderType>, parser, |
(table, arraysize(table), PROVIDER_TYPE_MAX)); |