diff options
author | bartfab <bartfab@chromium.org> | 2015-03-18 16:58:36 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-18 23:59:30 +0000 |
commit | 82bb909334491a927f4e77ae5e2f0326fe4da0e2 (patch) | |
tree | 430d33fdec0f616ed32d82cdc48e2b5e964b88eb /chromeos | |
parent | 07840d895caf8b511ffd2209d3ce2ffb1ae4efe7 (diff) | |
download | chromium_src-82bb909334491a927f4e77ae5e2f0326fe4da0e2.zip chromium_src-82bb909334491a927f4e77ae5e2f0326fe4da0e2.tar.gz chromium_src-82bb909334491a927f4e77ae5e2f0326fe4da0e2.tar.bz2 |
Add an ONC property for the third-party VPN provider extension ID
This CL maps the third-party VPN provider extension ID (which is
stored in shill's |Provider.Host| field) to an ONC property.
BUG=460428
TEST=Extended unit tests and API test
Review URL: https://codereview.chromium.org/1019033002
Cr-Commit-Position: refs/heads/master@{#321238}
Diffstat (limited to 'chromeos')
-rw-r--r-- | chromeos/network/network_state.cc | 43 | ||||
-rw-r--r-- | chromeos/network/network_state.h | 15 | ||||
-rw-r--r-- | chromeos/network/network_state_unittest.cc | 28 | ||||
-rw-r--r-- | chromeos/network/onc/onc_normalizer.cc | 1 | ||||
-rw-r--r-- | chromeos/network/onc/onc_signature.cc | 9 | ||||
-rw-r--r-- | chromeos/network/onc/onc_signature.h | 1 | ||||
-rw-r--r-- | chromeos/network/onc/onc_translator_onc_to_shill.cc | 26 | ||||
-rw-r--r-- | chromeos/network/onc/onc_translator_shill_to_onc.cc | 29 | ||||
-rw-r--r-- | chromeos/network/onc/onc_translator_unittest.cc | 7 | ||||
-rw-r--r-- | chromeos/network/onc/onc_validator.cc | 14 | ||||
-rw-r--r-- | chromeos/network/onc/onc_validator.h | 1 | ||||
-rw-r--r-- | chromeos/network/onc/onc_validator_unittest.cc | 7 | ||||
-rw-r--r-- | chromeos/test/data/network/invalid_settings_with_repairs.json | 9 | ||||
-rw-r--r-- | chromeos/test/data/network/shill_output_third_party_vpn.json | 8 | ||||
-rw-r--r-- | chromeos/test/data/network/shill_third_party_vpn.json | 6 | ||||
-rw-r--r-- | chromeos/test/data/network/third_party_vpn.onc | 11 |
16 files changed, 181 insertions, 34 deletions
diff --git a/chromeos/network/network_state.cc b/chromeos/network/network_state.cc index 609c9f0..f4ad959 100644 --- a/chromeos/network/network_state.cc +++ b/chromeos/network/network_state.cc @@ -4,6 +4,7 @@ #include "chromeos/network/network_state.h" +#include "base/memory/scoped_ptr.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" @@ -166,25 +167,29 @@ bool NetworkState::PropertyChanged(const std::string& key, } return true; } else if (key == shill::kProviderProperty) { + std::string vpn_provider_type; const base::DictionaryValue* dict; - std::string provider_type; if (!value.GetAsDictionary(&dict) || !dict->GetStringWithoutPathExpansion(shill::kTypeProperty, - &provider_type)) { + &vpn_provider_type)) { + NET_LOG(ERROR) << "Failed to parse " << path() << "." << key; return false; } - if (provider_type != shill::kProviderThirdPartyVpn) { - // If the network uses the built-in OpenVPN and L2TP support, set the - // provider extension ID to an empty string. - vpn_provider_extension_id_.clear(); - return true; + if (vpn_provider_type == shill::kProviderThirdPartyVpn) { + // If the network uses a third-party VPN provider, copy over the + // provider's extension ID, which is held in |shill::kHostProperty|. + if (!dict->GetStringWithoutPathExpansion( + shill::kHostProperty, &third_party_vpn_provider_extension_id_)) { + NET_LOG(ERROR) << "Failed to parse " << path() << "." << key; + return false; + } + } else { + third_party_vpn_provider_extension_id_.clear(); } - // If the network uses a third-party VPN provider, copy over the provider's - // extension ID, which is held in |shill::kHostProperty|. - return dict->GetStringWithoutPathExpansion(shill::kHostProperty, - &vpn_provider_extension_id_); + vpn_provider_type_ = vpn_provider_type; + return true; } return false; } @@ -232,6 +237,22 @@ void NetworkState::GetStateProperties(base::DictionaryValue* dictionary) const { connection_state()); } + // VPN properties. + if (NetworkTypePattern::VPN().MatchesType(type())) { + // Shill sends VPN provider properties in a nested dictionary. |dictionary| + // must replicate that nested structure. + scoped_ptr<base::DictionaryValue> provider_property( + new base::DictionaryValue); + provider_property->SetStringWithoutPathExpansion(shill::kTypeProperty, + vpn_provider_type_); + if (vpn_provider_type_ == shill::kProviderThirdPartyVpn) { + provider_property->SetStringWithoutPathExpansion( + shill::kHostProperty, third_party_vpn_provider_extension_id_); + } + dictionary->SetWithoutPathExpansion(shill::kProviderProperty, + provider_property.release()); + } + // Wireless properties if (!NetworkTypePattern::Wireless().MatchesType(type())) return; diff --git a/chromeos/network/network_state.h b/chromeos/network/network_state.h index c456909..e4d9cce 100644 --- a/chromeos/network/network_state.h +++ b/chromeos/network/network_state.h @@ -92,8 +92,11 @@ class CHROMEOS_EXPORT NetworkState : public ManagedState { const std::string& roaming() const { return roaming_; } const std::string& payment_url() const { return payment_url_; } bool cellular_out_of_credits() const { return cellular_out_of_credits_; } - const std::string& vpn_provider_extension_id() const { - return vpn_provider_extension_id_; + + // VPN property accessors + const std::string& vpn_provider_type() const { return vpn_provider_type_; } + const std::string& third_party_vpn_provider_extension_id() const { + return third_party_vpn_provider_extension_id_; } // Returns true if |connection_state_| is a connected/connecting state. @@ -183,10 +186,10 @@ class CHROMEOS_EXPORT NetworkState : public ManagedState { std::string payment_url_; bool cellular_out_of_credits_; - // VPN property. For networks using a third-party VPN provider, this will be - // the provider's extension ID. For networks using the built-in OpenVPN and - // L2TP support, this will be an empty string. - std::string vpn_provider_extension_id_; + // VPN properties, used to construct the display name and to show the correct + // configuration dialog. + std::string vpn_provider_type_; + std::string third_party_vpn_provider_extension_id_; // TODO(pneubeck): Remove this once (Managed)NetworkConfigurationHandler // provides proxy configuration. crbug.com/241775 diff --git a/chromeos/network/network_state_unittest.cc b/chromeos/network/network_state_unittest.cc index aa636d7..3ba359a 100644 --- a/chromeos/network/network_state_unittest.cc +++ b/chromeos/network/network_state_unittest.cc @@ -54,11 +54,14 @@ class NetworkStateTest : public testing::Test { } protected: + bool SetProperty(const std::string& key, scoped_ptr<base::Value> value) { + const bool result = network_state_.PropertyChanged(key, *value); + properties_.SetWithoutPathExpansion(key, value.release()); + return result; + } + bool SetStringProperty(const std::string& key, const std::string& value) { - TestStringValue* string_value = new TestStringValue(value); - bool res = network_state_.PropertyChanged(key, *string_value); - properties_.SetWithoutPathExpansion(key, string_value); - return res; + return SetProperty(key, make_scoped_ptr(new TestStringValue(value))); } bool SignalInitialPropertiesReceived() { @@ -213,4 +216,21 @@ TEST_F(NetworkStateTest, CaptivePortalState) { EXPECT_TRUE(network_state_.is_captive_portal()); } +// Third-party VPN provider. +TEST_F(NetworkStateTest, VPNThirdPartyProvider) { + EXPECT_TRUE(SetStringProperty(shill::kTypeProperty, shill::kTypeVPN)); + EXPECT_TRUE(SetStringProperty(shill::kNameProperty, "VPN")); + + scoped_ptr<base::DictionaryValue> provider(new base::DictionaryValue); + provider->SetStringWithoutPathExpansion(shill::kTypeProperty, + shill::kProviderThirdPartyVpn); + provider->SetStringWithoutPathExpansion( + shill::kHostProperty, "third-party-vpn-provider-extension-id"); + EXPECT_TRUE(SetProperty(shill::kProviderProperty, provider.Pass())); + SignalInitialPropertiesReceived(); + EXPECT_EQ(network_state_.vpn_provider_type(), shill::kProviderThirdPartyVpn); + EXPECT_EQ(network_state_.third_party_vpn_provider_extension_id(), + "third-party-vpn-provider-extension-id"); +} + } // namespace chromeos diff --git a/chromeos/network/onc/onc_normalizer.cc b/chromeos/network/onc/onc_normalizer.cc index 4ec5ddf..627835a 100644 --- a/chromeos/network/onc/onc_normalizer.cc +++ b/chromeos/network/onc/onc_normalizer.cc @@ -232,6 +232,7 @@ void Normalizer::NormalizeVPN(base::DictionaryValue* vpn) { RemoveEntryUnless(vpn, kOpenVPN, type == kOpenVPN); RemoveEntryUnless(vpn, kIPsec, type == kIPsec || type == kTypeL2TP_IPsec); RemoveEntryUnless(vpn, kL2TP, type == kTypeL2TP_IPsec); + RemoveEntryUnless(vpn, kThirdPartyVpn, type == kThirdPartyVpn); } void Normalizer::NormalizeWiFi(base::DictionaryValue* wifi) { diff --git a/chromeos/network/onc/onc_signature.cc b/chromeos/network/onc/onc_signature.cc index a421909..ad05682 100644 --- a/chromeos/network/onc/onc_signature.cc +++ b/chromeos/network/onc/onc_signature.cc @@ -151,6 +151,11 @@ const OncFieldSignature openvpn_fields[] = { { ::onc::openvpn::kVerifyX509, &kVerifyX509Signature}, {NULL}}; +const OncFieldSignature third_party_vpn_fields[] = { + { ::onc::kRecommended, &kRecommendedSignature}, + { ::onc::third_party_vpn::kExtensionID, &kStringSignature}, + {NULL}}; + const OncFieldSignature verify_x509_fields[] = { { ::onc::verify_x509::kName, &kStringSignature}, { ::onc::verify_x509::kType, &kStringSignature}, @@ -163,6 +168,7 @@ const OncFieldSignature vpn_fields[] = { { ::onc::vpn::kIPsec, &kIPsecSignature}, { ::onc::vpn::kL2TP, &kL2TPSignature}, { ::onc::vpn::kOpenVPN, &kOpenVPNSignature}, + { ::onc::vpn::kThirdPartyVpn, &kThirdPartyVPNSignature}, { ::onc::vpn::kType, &kStringSignature}, {NULL}}; @@ -385,6 +391,9 @@ const OncValueSignature kL2TPSignature = { const OncValueSignature kOpenVPNSignature = { base::Value::TYPE_DICTIONARY, openvpn_fields, NULL }; +const OncValueSignature kThirdPartyVPNSignature = { + base::Value::TYPE_DICTIONARY, third_party_vpn_fields, NULL +}; const OncValueSignature kVerifyX509Signature = { base::Value::TYPE_DICTIONARY, verify_x509_fields, NULL }; diff --git a/chromeos/network/onc/onc_signature.h b/chromeos/network/onc/onc_signature.h index acb8406..316ee86 100644 --- a/chromeos/network/onc/onc_signature.h +++ b/chromeos/network/onc/onc_signature.h @@ -43,6 +43,7 @@ CHROMEOS_EXPORT extern const OncValueSignature kIPsecSignature; CHROMEOS_EXPORT extern const OncValueSignature kL2TPSignature; CHROMEOS_EXPORT extern const OncValueSignature kXAUTHSignature; CHROMEOS_EXPORT extern const OncValueSignature kOpenVPNSignature; +CHROMEOS_EXPORT extern const OncValueSignature kThirdPartyVPNSignature; CHROMEOS_EXPORT extern const OncValueSignature kVerifyX509Signature; CHROMEOS_EXPORT extern const OncValueSignature kVPNSignature; CHROMEOS_EXPORT extern const OncValueSignature kEthernetSignature; diff --git a/chromeos/network/onc/onc_translator_onc_to_shill.cc b/chromeos/network/onc/onc_translator_onc_to_shill.cc index fdd8fbd..3cf9789f 100644 --- a/chromeos/network/onc/onc_translator_onc_to_shill.cc +++ b/chromeos/network/onc/onc_translator_onc_to_shill.cc @@ -188,10 +188,28 @@ void LocalTranslator::TranslateIPsec() { } void LocalTranslator::TranslateVPN() { - CopyFieldFromONCToShill(::onc::vpn::kHost, shill::kProviderHostProperty); - std::string type; - if (onc_object_->GetStringWithoutPathExpansion(::onc::vpn::kType, &type)) - TranslateWithTableAndSet(type, kVPNTypeTable, shill::kProviderTypeProperty); + std::string onc_type; + if (onc_object_->GetStringWithoutPathExpansion(::onc::vpn::kType, + &onc_type)) { + TranslateWithTableAndSet(onc_type, kVPNTypeTable, + shill::kProviderTypeProperty); + } + if (onc_type == ::onc::vpn::kThirdPartyVpn) { + // For third-party VPNs, |shill::kProviderHostProperty| is used to store the + // provider's extension ID. + const base::DictionaryValue* onc_third_party_vpn = nullptr; + onc_object_->GetDictionaryWithoutPathExpansion(::onc::vpn::kThirdPartyVpn, + &onc_third_party_vpn); + std::string onc_extension_id; + if (onc_third_party_vpn && + onc_third_party_vpn->GetStringWithoutPathExpansion( + ::onc::third_party_vpn::kExtensionID, &onc_extension_id)) { + shill_dictionary_->SetStringWithoutPathExpansion( + shill::kProviderHostProperty, onc_extension_id); + } + } else { + CopyFieldFromONCToShill(::onc::vpn::kHost, shill::kProviderHostProperty); + } CopyFieldsAccordingToSignature(); } diff --git a/chromeos/network/onc/onc_translator_shill_to_onc.cc b/chromeos/network/onc/onc_translator_shill_to_onc.cc index 1ec647a..43e7b3a 100644 --- a/chromeos/network/onc/onc_translator_shill_to_onc.cc +++ b/chromeos/network/onc/onc_translator_shill_to_onc.cc @@ -77,6 +77,7 @@ class ShillToONCTranslator { void TranslateEthernet(); void TranslateOpenVPN(); void TranslateIPsec(); + void TranslateThirdPartyVPN(); void TranslateVPN(); void TranslateWiFiWithState(); void TranslateWiMAXWithState(); @@ -159,6 +160,8 @@ ShillToONCTranslator::CreateTranslatedONCObject() { TranslateOpenVPN(); } else if (onc_signature_ == &kIPsecSignature) { TranslateIPsec(); + } else if (onc_signature_ == &kThirdPartyVPNSignature) { + TranslateThirdPartyVPN(); } else if (onc_signature_ == &kWiFiWithStateSignature) { TranslateWiFiWithState(); } else if (onc_signature_ == &kWiMAXWithStateSignature) { @@ -266,6 +269,18 @@ void ShillToONCTranslator::TranslateIPsec() { authentication_type); } +void ShillToONCTranslator::TranslateThirdPartyVPN() { + CopyPropertiesAccordingToSignature(); + + // For third-party VPNs, |shill::kProviderHostProperty| is used to store the + // provider's extension ID. + std::string shill_extension_id; + shill_dictionary_->GetStringWithoutPathExpansion(shill::kHostProperty, + &shill_extension_id); + onc_object_->SetStringWithoutPathExpansion( + ::onc::third_party_vpn::kExtensionID, shill_extension_id); +} + void ShillToONCTranslator::TranslateVPN() { CopyPropertiesAccordingToSignature(); @@ -285,11 +300,12 @@ void ShillToONCTranslator::TranslateVPN() { } onc_object_->SetStringWithoutPathExpansion(::onc::vpn::kType, onc_provider_type); - std::string provider_host; - if (provider->GetStringWithoutPathExpansion(shill::kHostProperty, - &provider_host)) { + std::string shill_provider_host; + if (onc_provider_type != ::onc::vpn::kThirdPartyVpn && + provider->GetStringWithoutPathExpansion(shill::kHostProperty, + &shill_provider_host)) { onc_object_->SetStringWithoutPathExpansion(::onc::vpn::kHost, - provider_host); + shill_provider_host); } // Translate the nested dictionary. @@ -298,13 +314,14 @@ void ShillToONCTranslator::TranslateVPN() { TranslateAndAddNestedObject(::onc::vpn::kIPsec, *provider); TranslateAndAddNestedObject(::onc::vpn::kL2TP, *provider); provider_type_dictionary = ::onc::vpn::kIPsec; - } else if (onc_provider_type != ::onc::vpn::kThirdPartyVpn) { + } else { TranslateAndAddNestedObject(onc_provider_type, *provider); provider_type_dictionary = onc_provider_type; } bool save_credentials; - if (shill_dictionary_->GetBooleanWithoutPathExpansion( + if (onc_provider_type != ::onc::vpn::kThirdPartyVpn && + shill_dictionary_->GetBooleanWithoutPathExpansion( shill::kSaveCredentialsProperty, &save_credentials)) { SetNestedOncValue(provider_type_dictionary, ::onc::vpn::kSaveCredentials, diff --git a/chromeos/network/onc/onc_translator_unittest.cc b/chromeos/network/onc/onc_translator_unittest.cc index 9444614..f637761 100644 --- a/chromeos/network/onc/onc_translator_unittest.cc +++ b/chromeos/network/onc/onc_translator_unittest.cc @@ -61,7 +61,8 @@ INSTANTIATE_TEST_CASE_P( std::make_pair("openvpn_clientcert_with_cert_pems.onc", "shill_openvpn_clientcert.json"), std::make_pair("cellular.onc", "shill_cellular.json"), - std::make_pair("wimax.onc", "shill_wimax.json"))); + std::make_pair("wimax.onc", "shill_wimax.json"), + std::make_pair("third_party_vpn.onc", "shill_third_party_vpn.json"))); // First parameter: Filename of source Shill json. // Second parameter: Filename of expected translated ONC network part. @@ -113,7 +114,9 @@ INSTANTIATE_TEST_CASE_P( std::make_pair("shill_cellular_with_state.json", "translation_of_shill_cellular_with_state.onc"), std::make_pair("shill_wimax_with_state.json", - "translation_of_shill_wimax_with_state.onc"))); + "translation_of_shill_wimax_with_state.onc"), + std::make_pair("shill_output_third_party_vpn.json", + "third_party_vpn.onc"))); } // namespace onc } // namespace chromeos diff --git a/chromeos/network/onc/onc_validator.cc b/chromeos/network/onc/onc_validator.cc index c3cd2bb..e3ea49a 100644 --- a/chromeos/network/onc/onc_validator.cc +++ b/chromeos/network/onc/onc_validator.cc @@ -122,6 +122,8 @@ scoped_ptr<base::DictionaryValue> Validator::MapObject( valid = ValidateIPsec(repaired.get()); } else if (&signature == &kOpenVPNSignature) { valid = ValidateOpenVPN(repaired.get()); + } else if (&signature == &kThirdPartyVPNSignature) { + valid = ValidateThirdPartyVPN(repaired.get()); } else if (&signature == &kVerifyX509Signature) { valid = ValidateVerifyX509(repaired.get()); } else if (&signature == &kCertificatePatternSignature) { @@ -683,7 +685,8 @@ bool Validator::ValidateWiFi(base::DictionaryValue* result) { bool Validator::ValidateVPN(base::DictionaryValue* result) { using namespace ::onc::vpn; - const char* const kValidTypes[] = {kIPsec, kTypeL2TP_IPsec, kOpenVPN}; + const char* const kValidTypes[] = { + kIPsec, kTypeL2TP_IPsec, kOpenVPN, kThirdPartyVpn}; const std::vector<const char*> valid_types(toVector(kValidTypes)); if (FieldExistsAndHasNoValidValue(*result, ::onc::vpn::kType, valid_types)) return false; @@ -698,6 +701,8 @@ bool Validator::ValidateVPN(base::DictionaryValue* result) { } else if (type == kTypeL2TP_IPsec) { all_required_exist &= RequireField(*result, kIPsec) && RequireField(*result, kL2TP); + } else if (type == kThirdPartyVpn) { + all_required_exist &= RequireField(*result, kThirdPartyVpn); } return !error_on_missing_field_ || all_required_exist; @@ -802,6 +807,13 @@ bool Validator::ValidateOpenVPN(base::DictionaryValue* result) { return !error_on_missing_field_ || all_required_exist; } +bool Validator::ValidateThirdPartyVPN(base::DictionaryValue* result) { + const bool all_required_exist = + RequireField(*result, ::onc::third_party_vpn::kExtensionID); + + return !error_on_missing_field_ || all_required_exist; +} + bool Validator::ValidateVerifyX509(base::DictionaryValue* result) { using namespace ::onc::verify_x509; diff --git a/chromeos/network/onc/onc_validator.h b/chromeos/network/onc/onc_validator.h index b535f9f..424f7eb 100644 --- a/chromeos/network/onc/onc_validator.h +++ b/chromeos/network/onc/onc_validator.h @@ -160,6 +160,7 @@ class CHROMEOS_EXPORT Validator : public Mapper { bool ValidateVPN(base::DictionaryValue* result); bool ValidateIPsec(base::DictionaryValue* result); bool ValidateOpenVPN(base::DictionaryValue* result); + bool ValidateThirdPartyVPN(base::DictionaryValue* result); bool ValidateVerifyX509(base::DictionaryValue* result); bool ValidateCertificatePattern(base::DictionaryValue* result); bool ValidateProxySettings(base::DictionaryValue* result); diff --git a/chromeos/network/onc/onc_validator_unittest.cc b/chromeos/network/onc/onc_validator_unittest.cc index add3572..8517f71 100644 --- a/chromeos/network/onc/onc_validator_unittest.cc +++ b/chromeos/network/onc/onc_validator_unittest.cc @@ -208,6 +208,9 @@ INSTANTIATE_TEST_CASE_P( false), OncParams("openvpn_with_password.onc", &kNetworkConfigurationSignature, + false), + OncParams("third_party_vpn.onc", + &kNetworkConfigurationSignature, false))); namespace { @@ -348,6 +351,10 @@ INSTANTIATE_TEST_CASE_P( std::make_pair(OncParams("openvpn-missing-verify-x509-name", &kNetworkConfigurationSignature, false), + ExpectStrictNotValid("")), + std::make_pair(OncParams("third-party-vpn-missing-extension-id", + &kNetworkConfigurationSignature, + false), ExpectStrictNotValid("")))); // Strict validator returns INVALID. Liberal validator repairs. diff --git a/chromeos/test/data/network/invalid_settings_with_repairs.json b/chromeos/test/data/network/invalid_settings_with_repairs.json index 67c375be..d9d4b6d 100644 --- a/chromeos/test/data/network/invalid_settings_with_repairs.json +++ b/chromeos/test/data/network/invalid_settings_with_repairs.json @@ -396,6 +396,15 @@ } } }, + "third-party-vpn-missing-extension-id": { + "GUID": "guid", + "Name": "third-party VPN", + "Type": "VPN", + "VPN": { + "Type": "ThirdPartyVPN", + "ThirdPartyVPN": { } + } + }, "toplevel-empty": { "Type": "UnencryptedConfiguration", "NetworkConfigurations": [ ] diff --git a/chromeos/test/data/network/shill_output_third_party_vpn.json b/chromeos/test/data/network/shill_output_third_party_vpn.json new file mode 100644 index 0000000..382f2f4 --- /dev/null +++ b/chromeos/test/data/network/shill_output_third_party_vpn.json @@ -0,0 +1,8 @@ +{ "GUID": "guid", + "Type": "vpn", + "Name": "third-party VPN", + "Provider": { + "Host": "deadbeefdeadbeefdeadbeefdeadbeef", + "Type": "thirdpartyvpn", + }, +} diff --git a/chromeos/test/data/network/shill_third_party_vpn.json b/chromeos/test/data/network/shill_third_party_vpn.json new file mode 100644 index 0000000..9ee0fe0 --- /dev/null +++ b/chromeos/test/data/network/shill_third_party_vpn.json @@ -0,0 +1,6 @@ +{ "GUID": "guid", + "Type": "vpn", + "Name": "third-party VPN", + "Provider.Host": "deadbeefdeadbeefdeadbeefdeadbeef", + "Provider.Type": "thirdpartyvpn", +} diff --git a/chromeos/test/data/network/third_party_vpn.onc b/chromeos/test/data/network/third_party_vpn.onc new file mode 100644 index 0000000..e062178 --- /dev/null +++ b/chromeos/test/data/network/third_party_vpn.onc @@ -0,0 +1,11 @@ +{ + "GUID": "guid", + "Name": "third-party VPN", + "Type": "VPN", + "VPN": { + "Type": "ThirdPartyVPN", + "ThirdPartyVPN": { + "ExtensionID": "deadbeefdeadbeefdeadbeefdeadbeef", + } + } +} |