summaryrefslogtreecommitdiffstats
path: root/chromeos/network
diff options
context:
space:
mode:
authorpneubeck@chromium.org <pneubeck@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-11 11:21:18 +0000
committerpneubeck@chromium.org <pneubeck@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-01-11 11:21:18 +0000
commite3b3e4f790dec14739d71fc5fe75b3652153527e (patch)
tree09511b22b22b70170b7b0273df93e0b14fbacbd8 /chromeos/network
parent0ec80e47c37ccb656cca1d9620fda80809f94692 (diff)
downloadchromium_src-e3b3e4f790dec14739d71fc5fe75b3652153527e.zip
chromium_src-e3b3e4f790dec14739d71fc5fe75b3652153527e.tar.gz
chromium_src-e3b3e4f790dec14739d71fc5fe75b3652153527e.tar.bz2
Extending the translation from ONC to Shill.
Added string expansion and UIData creation. BUG=162040,147624 TBR=jochen@chromium.org (for gypi changes) Review URL: https://chromiumcodereview.appspot.com/11664005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@176312 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chromeos/network')
-rw-r--r--chromeos/network/onc/onc_certificate_importer.cc4
-rw-r--r--chromeos/network/onc/onc_certificate_importer.h4
-rw-r--r--chromeos/network/onc/onc_signature.cc36
-rw-r--r--chromeos/network/onc/onc_signature.h5
-rw-r--r--chromeos/network/onc/onc_translation_tables.cc32
-rw-r--r--chromeos/network/onc/onc_translation_tables.h4
-rw-r--r--chromeos/network/onc/onc_translator_onc_to_shill.cc64
-rw-r--r--chromeos/network/onc/onc_translator_shill_to_onc.cc7
-rw-r--r--chromeos/network/onc/onc_translator_unittest.cc11
-rw-r--r--chromeos/network/onc/onc_utils.cc57
-rw-r--r--chromeos/network/onc/onc_utils.h32
-rw-r--r--chromeos/network/onc/onc_utils_unittest.cc50
12 files changed, 274 insertions, 32 deletions
diff --git a/chromeos/network/onc/onc_certificate_importer.cc b/chromeos/network/onc/onc_certificate_importer.cc
index e1ae94b..451c6d9 100644
--- a/chromeos/network/onc/onc_certificate_importer.cc
+++ b/chromeos/network/onc/onc_certificate_importer.cc
@@ -370,5 +370,5 @@ bool CertificateImporter::ParseClientCertificate(
return true;
}
-} // chromeos
-} // onc
+} // namespace onc
+} // namespace chromeos
diff --git a/chromeos/network/onc/onc_certificate_importer.h b/chromeos/network/onc/onc_certificate_importer.h
index bb64f81..1fed941 100644
--- a/chromeos/network/onc/onc_certificate_importer.h
+++ b/chromeos/network/onc/onc_certificate_importer.h
@@ -85,7 +85,7 @@ class CHROMEOS_EXPORT CertificateImporter {
DISALLOW_COPY_AND_ASSIGN(CertificateImporter);
};
-} // chromeos
-} // onc
+} // namespace onc
+} // namespace chromeos
#endif // CHROMEOS_NETWORK_ONC_ONC_CERTIFICATE_IMPORTER_H_
diff --git a/chromeos/network/onc/onc_signature.cc b/chromeos/network/onc/onc_signature.cc
index 974df42..1603c57 100644
--- a/chromeos/network/onc/onc_signature.cc
+++ b/chromeos/network/onc/onc_signature.cc
@@ -37,6 +37,8 @@ const OncFieldSignature issuer_subject_pattern_fields[] = {
{ NULL }
};
+// CertificatePattern is converted with function CreateUIData(...) to UIData
+// stored in Shill.
const OncFieldSignature certificate_pattern_fields[] = {
{ kRecommended, NULL, &kRecommendedSignature },
{ certificate::kEnrollmentURI, NULL, &kStringListSignature },
@@ -54,8 +56,10 @@ const OncFieldSignature eap_fields[] = {
{ eap::kClientCertRef, NULL, &kStringSignature },
{ eap::kClientCertType, NULL, &kStringSignature },
{ eap::kIdentity, flimflam::kEapIdentityProperty, &kStringSignature },
- { eap::kInner, flimflam::kEapPhase2AuthProperty, &kStringSignature },
- { eap::kOuter, flimflam::kEapMethodProperty, &kStringSignature },
+ // This field is converted during translation, see onc_translator_*.
+ { eap::kInner, NULL, &kStringSignature },
+ // This field is converted during translation, see onc_translator_*.
+ { eap::kOuter, NULL, &kStringSignature },
{ eap::kPassword, flimflam::kEapPasswordProperty, &kStringSignature },
{ eap::kSaveCredentials, flimflam::kSaveCredentialsProperty,
&kBoolSignature },
@@ -126,6 +130,7 @@ const OncFieldSignature openvpn_fields[] = {
{ vpn::kSaveCredentials, flimflam::kSaveCredentialsProperty,
&kBoolSignature },
{ vpn::kServerCARef, flimflam::kOpenVPNCaCertNSSProperty, &kStringSignature },
+ // Not supported, yet.
{ vpn::kServerCertRef, NULL, &kStringSignature },
{ vpn::kServerPollTimeout, flimflam::kOpenVPNServerPollTimeoutProperty,
&kIntegerSignature },
@@ -136,6 +141,7 @@ const OncFieldSignature openvpn_fields[] = {
&kStringSignature },
{ vpn::kTLSRemote, flimflam::kOpenVPNTLSRemoteProperty, &kStringSignature },
{ vpn::kUsername, flimflam::kOpenVPNUserProperty, &kStringSignature },
+ // Not supported, yet.
{ vpn::kVerb, NULL, &kStringSignature },
{ NULL }
};
@@ -147,25 +153,26 @@ const OncFieldSignature vpn_fields[] = {
{ vpn::kL2TP, NULL, &kL2TPSignature },
{ vpn::kOpenVPN, NULL, &kOpenVPNSignature },
// This field is converted during translation, see onc_translator_*.
- { kType, NULL, &kStringSignature },
+ { vpn::kType, NULL, &kStringSignature },
{ NULL }
};
const OncFieldSignature ethernet_fields[] = {
{ kRecommended, NULL, &kRecommendedSignature },
+ // Not supported, yet.
{ ethernet::kAuthentication, NULL, &kStringSignature },
{ ethernet::kEAP, NULL, &kEAPSignature },
{ NULL }
};
+// Not supported, yet.
const OncFieldSignature ipconfig_fields[] = {
{ ipconfig::kGateway, NULL, &kStringSignature },
{ ipconfig::kIPAddress, NULL, &kStringSignature },
{ kNameServers, NULL, &kStringSignature },
{ ipconfig::kRoutingPrefix, NULL, &kIntegerSignature },
{ kSearchDomains, NULL, &kStringListSignature },
- // This field is converted during translation, see onc_translator_*.
- { kType, NULL, &kStringSignature },
+ { ipconfig::kType, NULL, &kStringSignature },
{ NULL }
};
@@ -183,12 +190,14 @@ const OncFieldSignature proxy_manual_fields[] = {
{ NULL }
};
+// Proxy settings are converted to Shill by
+// function ConvertOncProxySettingsToProxyConfig(...).
const OncFieldSignature proxy_settings_fields[] = {
{ kRecommended, NULL, &kRecommendedSignature },
{ proxy::kExcludeDomains, NULL, &kStringListSignature },
{ proxy::kManual, NULL, &kProxyManualSignature },
{ proxy::kPAC, NULL, &kStringSignature },
- { kType, NULL, &kStringSignature },
+ { proxy::kType, NULL, &kStringSignature },
{ NULL }
};
@@ -199,7 +208,8 @@ const OncFieldSignature wifi_fields[] = {
{ wifi::kHiddenSSID, flimflam::kWifiHiddenSsid, &kBoolSignature },
{ wifi::kPassphrase, flimflam::kPassphraseProperty, &kStringSignature },
{ wifi::kSSID, flimflam::kSSIDProperty, &kStringSignature },
- { wifi::kSecurity, flimflam::kSecurityProperty, &kStringSignature },
+ // This field is converted during translation, see onc_translator_*.
+ { wifi::kSecurity, NULL, &kStringSignature },
{ NULL }
};
@@ -208,10 +218,15 @@ const OncFieldSignature network_configuration_fields[] = {
{ kEthernet, NULL, &kEthernetSignature },
{ kGUID, flimflam::kGuidProperty, &kStringSignature },
{ kIPConfigs, NULL, &kIPConfigListSignature },
- { kName, flimflam::kNameProperty, &kStringSignature },
+ // Shill doesn't allow setting the name for non-VPN networks.
+ // This field is conditionally translated, see onc_translator_*.
+ { kName, NULL, &kStringSignature },
+ // Not supported, yet.
{ kNameServers, NULL, &kStringListSignature },
{ kProxySettings, NULL, &kProxySettingsSignature },
+ // No need to translate.
{ kRemove, NULL, &kBoolSignature },
+ // Not supported, yet.
{ kSearchDomains, NULL, &kStringListSignature },
// This field is converted during translation, see onc_translator_*.
{ kType, NULL, &kStringSignature },
@@ -220,12 +235,13 @@ const OncFieldSignature network_configuration_fields[] = {
{ NULL }
};
+// Certificates are not translated to Shill.
const OncFieldSignature certificate_fields[] = {
- { kGUID, flimflam::kGuidProperty, &kStringSignature },
+ { kGUID, NULL, &kStringSignature },
{ certificate::kPKCS12, NULL, &kStringSignature },
{ kRemove, NULL, &kBoolSignature },
{ certificate::kTrust, NULL, &kStringListSignature },
- { kType, NULL, &kStringSignature },
+ { certificate::kType, NULL, &kStringSignature },
{ certificate::kX509, NULL, &kStringSignature },
{ NULL }
};
diff --git a/chromeos/network/onc/onc_signature.h b/chromeos/network/onc/onc_signature.h
index 7ef17c0..71ab0af 100644
--- a/chromeos/network/onc/onc_signature.h
+++ b/chromeos/network/onc/onc_signature.h
@@ -27,8 +27,9 @@ struct CHROMEOS_EXPORT OncValueSignature {
const OncValueSignature* onc_array_entry_signature;
};
-const OncFieldSignature* GetFieldSignature(const OncValueSignature& signature,
- const std::string& onc_field_name);
+CHROMEOS_EXPORT const OncFieldSignature* GetFieldSignature(
+ const OncValueSignature& signature,
+ const std::string& onc_field_name);
CHROMEOS_EXPORT extern const OncValueSignature kRecommendedSignature;
CHROMEOS_EXPORT extern const OncValueSignature kEAPSignature;
diff --git a/chromeos/network/onc/onc_translation_tables.cc b/chromeos/network/onc/onc_translation_tables.cc
index abe978f..6dc4a8f 100644
--- a/chromeos/network/onc/onc_translation_tables.cc
+++ b/chromeos/network/onc/onc_translation_tables.cc
@@ -26,5 +26,37 @@ const StringTranslationEntry kVPNTypeTable[] = {
{ NULL }
};
+const StringTranslationEntry kWiFiSecurityTable[] = {
+ { wifi::kNone, flimflam::kSecurityNone },
+ { wifi::kWEP_PSK, flimflam::kSecurityWep },
+ { wifi::kWPA_PSK, flimflam::kSecurityPsk },
+ { wifi::kWPA_EAP, flimflam::kSecurity8021x },
+ { NULL }
+};
+
+const StringTranslationEntry kEAPOuterTable[] = {
+ { eap::kPEAP, flimflam::kEapMethodPEAP },
+ { eap::kEAP_TLS, flimflam::kEapMethodTLS },
+ { eap::kEAP_TTLS, flimflam::kEapMethodTTLS },
+ { eap::kLEAP, flimflam::kEapMethodLEAP },
+ { NULL }
+};
+
+// Translation of the EAP.Inner field in case of EAP.Outer == PEAP
+const StringTranslationEntry kEAP_PEAP_InnerTable[] = {
+ { eap::kMD5, flimflam::kEapPhase2AuthPEAPMD5 },
+ { eap::kMSCHAPv2, flimflam::kEapPhase2AuthPEAPMSCHAPV2 },
+ { NULL }
+};
+
+// Translation of the EAP.Inner field in case of EAP.Outer == TTLS
+const StringTranslationEntry kEAP_TTLS_InnerTable[] = {
+ { eap::kMD5, flimflam::kEapPhase2AuthTTLSMD5 },
+ { eap::kMSCHAPv2, flimflam::kEapPhase2AuthTTLSMSCHAPV2 },
+ { eap::kPAP, flimflam::kEapPhase2AuthTTLSPAP },
+ { NULL }
+};
+
+
} // namespace onc
} // namespace chromeos
diff --git a/chromeos/network/onc/onc_translation_tables.h b/chromeos/network/onc/onc_translation_tables.h
index f9b54a8..276b132 100644
--- a/chromeos/network/onc/onc_translation_tables.h
+++ b/chromeos/network/onc/onc_translation_tables.h
@@ -17,6 +17,10 @@ struct StringTranslationEntry {
// These are NULL-terminated arrays.
extern const StringTranslationEntry kNetworkTypeTable[];
extern const StringTranslationEntry kVPNTypeTable[];
+extern const StringTranslationEntry kWiFiSecurityTable[];
+extern const StringTranslationEntry kEAPOuterTable[];
+extern const StringTranslationEntry kEAP_PEAP_InnerTable[];
+extern const StringTranslationEntry kEAP_TTLS_InnerTable[];
} // namespace onc
} // namespace chromeos
diff --git a/chromeos/network/onc/onc_translator_onc_to_shill.cc b/chromeos/network/onc/onc_translator_onc_to_shill.cc
index cd8a4eb..6f38700 100644
--- a/chromeos/network/onc/onc_translator_onc_to_shill.cc
+++ b/chromeos/network/onc/onc_translator_onc_to_shill.cc
@@ -53,6 +53,8 @@ class LocalTranslator {
private:
void TranslateOpenVPN();
void TranslateVPN();
+ void TranslateWiFi();
+ void TranslateEAP();
void TranslateNetworkConfiguration();
// Copies all entries from |onc_object_| to |shill_dictionary_| for which a
@@ -86,6 +88,10 @@ void LocalTranslator::TranslateFields() {
TranslateVPN();
else if (onc_signature_ == &kOpenVPNSignature)
TranslateOpenVPN();
+ else if (onc_signature_ == &kWiFiSignature)
+ TranslateWiFi();
+ else if (onc_signature_ == &kEAPSignature)
+ TranslateEAP();
else
CopyFieldsAccordingToSignature();
}
@@ -115,13 +121,58 @@ void LocalTranslator::TranslateOpenVPN() {
}
void LocalTranslator::TranslateVPN() {
- TranslateWithTableAndSet(kType, kVPNTypeTable,
+ std::string type;
+ onc_object_->GetStringWithoutPathExpansion(kType, &type);
+ TranslateWithTableAndSet(type, kVPNTypeTable,
flimflam::kProviderTypeProperty);
+
+ CopyFieldsAccordingToSignature();
+}
+
+void LocalTranslator::TranslateWiFi() {
+ std::string security;
+ onc_object_->GetStringWithoutPathExpansion(wifi::kSecurity, &security);
+ TranslateWithTableAndSet(security, kWiFiSecurityTable,
+ flimflam::kSecurityProperty);
+
+ CopyFieldsAccordingToSignature();
+}
+
+void LocalTranslator::TranslateEAP() {
+ std::string outer;
+ onc_object_->GetStringWithoutPathExpansion(eap::kOuter, &outer);
+ TranslateWithTableAndSet(outer, kEAPOuterTable, flimflam::kEapMethodProperty);
+
+ // Translate the inner protocol only for outer tunneling protocols.
+ if (outer == eap::kPEAP || outer == eap::kEAP_TTLS) {
+ // In ONC the Inner protocol defaults to "Automatic".
+ std::string inner = eap::kAutomatic;
+ // ONC's Inner == "Automatic" translates to omitting the Phase2 property in
+ // Shill.
+ onc_object_->GetStringWithoutPathExpansion(eap::kInner, &inner);
+ if (inner != eap::kAutomatic) {
+ const StringTranslationEntry* table =
+ outer == eap::kPEAP ? kEAP_PEAP_InnerTable : kEAP_TTLS_InnerTable;
+ TranslateWithTableAndSet(inner, table, flimflam::kEapPhase2AuthProperty);
+ }
+ }
+
CopyFieldsAccordingToSignature();
}
void LocalTranslator::TranslateNetworkConfiguration() {
- TranslateWithTableAndSet(kType, kNetworkTypeTable, flimflam::kTypeProperty);
+ std::string type;
+ onc_object_->GetStringWithoutPathExpansion(kType, &type);
+ TranslateWithTableAndSet(type, kNetworkTypeTable, flimflam::kTypeProperty);
+
+ // Shill doesn't allow setting the name for non-VPN networks.
+ if (type == kVPN) {
+ std::string name;
+ onc_object_->GetStringWithoutPathExpansion(kName, &name);
+ shill_dictionary_->SetStringWithoutPathExpansion(
+ flimflam::kNameProperty, name);
+ }
+
CopyFieldsAccordingToSignature();
}
@@ -149,13 +200,9 @@ void LocalTranslator::AddValueAccordingToSignature(
}
void LocalTranslator::TranslateWithTableAndSet(
- const std::string& onc_field_name,
+ const std::string& onc_value,
const StringTranslationEntry table[],
const std::string& shill_property_name) {
- std::string onc_value;
- if (!onc_object_->GetStringWithoutPathExpansion(onc_field_name, &onc_value))
- return;
-
for (int i = 0; table[i].onc_value != NULL; ++i) {
if (onc_value != table[i].onc_value)
continue;
@@ -166,8 +213,7 @@ void LocalTranslator::TranslateWithTableAndSet(
// As we previously validate ONC, this case should never occur. If it still
// occurs, we should check here. Otherwise the failure will only show up much
// later in Shill.
- LOG(ERROR) << "Value '" << onc_value << "' for field '"
- << onc_field_name << "' cannot be translated to Shill";
+ LOG(ERROR) << "Value '" << onc_value << "cannot be translated to Shill";
}
// Iterates recursively over |onc_object| and its |signature|. At each object
diff --git a/chromeos/network/onc/onc_translator_shill_to_onc.cc b/chromeos/network/onc/onc_translator_shill_to_onc.cc
index c33e0a9..afdbaaf 100644
--- a/chromeos/network/onc/onc_translator_shill_to_onc.cc
+++ b/chromeos/network/onc/onc_translator_shill_to_onc.cc
@@ -179,6 +179,13 @@ void ShillToONCTranslator::TranslateNetworkConfiguration() {
std::string network_type;
if (onc_object_->GetStringWithoutPathExpansion(kType, &network_type))
TranslateAndAddNestedObject(network_type);
+
+ if (network_type == kVPN) {
+ std::string name;
+ shill_dictionary_->GetStringWithoutPathExpansion(flimflam::kNameProperty,
+ &name);
+ onc_object_->SetStringWithoutPathExpansion(kName, name);
+ }
}
void ShillToONCTranslator::CopyPropertiesAccordingToSignature() {
diff --git a/chromeos/network/onc/onc_translator_unittest.cc b/chromeos/network/onc/onc_translator_unittest.cc
index da9e658..2a256e2 100644
--- a/chromeos/network/onc/onc_translator_unittest.cc
+++ b/chromeos/network/onc/onc_translator_unittest.cc
@@ -42,8 +42,17 @@ INSTANTIATE_TEST_CASE_P(
ONCTranslatorOncToShillTest,
::testing::Values(
std::make_pair("managed_ethernet.onc", "shill_ethernet.json"),
+ std::make_pair("valid_wifi_psk.onc", "shill_wifi_psk.json"),
+ std::make_pair("valid_wifi_clientcert.onc",
+ "shill_wifi_clientcert.json"),
+ std::make_pair("valid_wifi_clientref.onc",
+ "shill_wifi_clientref.json"),
std::make_pair("valid_l2tpipsec.onc", "shill_l2tpipsec.json"),
- std::make_pair("valid_openvpn.onc", "shill_openvpn.json")));
+ std::make_pair("valid_l2tpipsec_clientcert.onc",
+ "shill_l2tpipsec_clientcert.json"),
+ std::make_pair("valid_openvpn.onc", "shill_openvpn.json"),
+ std::make_pair("valid_openvpn_clientcert.onc",
+ "shill_openvpn_clientcert.json")));
// Test the translation from Shill json to ONC.
//
diff --git a/chromeos/network/onc/onc_utils.cc b/chromeos/network/onc/onc_utils.cc
index 85cfe64..c66d1e8 100644
--- a/chromeos/network/onc/onc_utils.cc
+++ b/chromeos/network/onc/onc_utils.cc
@@ -7,9 +7,9 @@
#include "base/base64.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
+#include "base/string_util.h"
#include "base/values.h"
#include "chromeos/network/network_event_log.h"
-#include "chromeos/network/onc/onc_constants.h"
#include "crypto/encryptor.h"
#include "crypto/hmac.h"
#include "crypto/symmetric_key.h"
@@ -164,5 +164,56 @@ std::string GetSourceAsString(ONCSource source) {
return "unknown";
}
-} // chromeos
-} // onc
+void ExpandField(const std::string fieldname,
+ const StringSubstitution& substitution,
+ base::DictionaryValue* onc_object) {
+ std::string user_string;
+ if (!onc_object->GetStringWithoutPathExpansion(fieldname, &user_string))
+ return;
+
+ std::string login_id;
+ if (substitution.GetSubstitute(substitutes::kLoginIDField, &login_id)) {
+ ReplaceSubstringsAfterOffset(&user_string, 0,
+ onc::substitutes::kLoginIDField,
+ login_id);
+ }
+
+ std::string email;
+ if (substitution.GetSubstitute(substitutes::kEmailField, &email)) {
+ ReplaceSubstringsAfterOffset(&user_string, 0,
+ onc::substitutes::kEmailField,
+ email);
+ }
+
+ onc_object->SetStringWithoutPathExpansion(fieldname, user_string);
+}
+
+void ExpandStringsInOncObject(
+ const OncValueSignature& signature,
+ const StringSubstitution& substitution,
+ base::DictionaryValue* onc_object) {
+ if (&signature == &kEAPSignature) {
+ ExpandField(eap::kAnonymousIdentity, substitution, onc_object);
+ ExpandField(eap::kIdentity, substitution, onc_object);
+ } else if (&signature == &kL2TPSignature ||
+ &signature == &kOpenVPNSignature) {
+ ExpandField(vpn::kUsername, substitution, onc_object);
+ }
+
+ // Recurse into nested objects.
+ for (base::DictionaryValue::key_iterator it = onc_object->begin_keys();
+ it != onc_object->end_keys(); ++it) {
+ base::DictionaryValue* inner_object;
+ if (!onc_object->GetDictionaryWithoutPathExpansion(*it, &inner_object))
+ continue;
+
+ const OncFieldSignature* field_signature =
+ GetFieldSignature(signature, *it);
+
+ ExpandStringsInOncObject(*field_signature->value_signature,
+ substitution, inner_object);
+ }
+}
+
+} // namespace onc
+} // namespace chromeos
diff --git a/chromeos/network/onc/onc_utils.h b/chromeos/network/onc/onc_utils.h
index 13263a8..61ab3a4 100644
--- a/chromeos/network/onc/onc_utils.h
+++ b/chromeos/network/onc/onc_utils.h
@@ -7,9 +7,11 @@
#include <string>
+#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "chromeos/chromeos_export.h"
#include "chromeos/network/onc/onc_constants.h"
+#include "chromeos/network/onc/onc_signature.h"
namespace base {
class DictionaryValue;
@@ -28,7 +30,7 @@ CHROMEOS_EXPORT extern const char kEmptyUnencryptedConfiguration[];
CHROMEOS_EXPORT scoped_ptr<base::DictionaryValue> ReadDictionaryFromJson(
const std::string& json);
-// Decrypt the given EncryptedConfiguration |onc| (see the ONC specification)
+// Decrypts the given EncryptedConfiguration |onc| (see the ONC specification)
// using |passphrase|. The resulting UnencryptedConfiguration is returned. If an
// error occurs, returns NULL.
CHROMEOS_EXPORT scoped_ptr<base::DictionaryValue> Decrypt(
@@ -38,7 +40,31 @@ CHROMEOS_EXPORT scoped_ptr<base::DictionaryValue> Decrypt(
// For logging only: strings not user facing.
CHROMEOS_EXPORT std::string GetSourceAsString(ONCSource source);
-} // chromeos
-} // onc
+// Used for string expansion with function ExpandStringInOncObject(...).
+class CHROMEOS_EXPORT StringSubstitution {
+ public:
+ StringSubstitution() {}
+ virtual ~StringSubstitution() {}
+
+ // Returns the replacement string for |placeholder| in
+ // |substitute|. Currently, onc::substitutes::kLoginIDField and
+ // onc::substitutes::kEmailField are supported.
+ virtual bool GetSubstitute(std::string placeholder,
+ std::string* substitute) const = 0;
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StringSubstitution);
+};
+
+// Replaces all expandable fields that are mentioned in the ONC
+// specification. The object of |onc_object| is modified in place. Currently
+// onc::substitutes::kLoginIDField and onc::substitutes::kEmailField are
+// expanded. The replacement strings are obtained from |substitution|.
+CHROMEOS_EXPORT void ExpandStringsInOncObject(
+ const OncValueSignature& signature,
+ const StringSubstitution& substitution,
+ base::DictionaryValue* onc_object);
+
+} // namespace onc
+} // namespace chromeos
#endif // CHROMEOS_NETWORK_ONC_ONC_UTILS_H_
diff --git a/chromeos/network/onc/onc_utils_unittest.cc b/chromeos/network/onc/onc_utils_unittest.cc
index 93ed390..f2226b1 100644
--- a/chromeos/network/onc/onc_utils_unittest.cc
+++ b/chromeos/network/onc/onc_utils_unittest.cc
@@ -49,5 +49,55 @@ TEST(ONCDecrypterTest, LoadEncryptedOnc) {
actual_decrypted_onc.get()));
}
+namespace {
+
+const char* kLoginId = "hans";
+const char* kLoginEmail = "hans@my.domain.com";
+
+class StringSubstitutionStub : public StringSubstitution {
+ public:
+ StringSubstitutionStub() {}
+ virtual bool GetSubstitute(std::string placeholder,
+ std::string* substitute) const {
+ if (placeholder == substitutes::kLoginIDField)
+ *substitute = kLoginId;
+ else if (placeholder == substitutes::kEmailField)
+ *substitute = kLoginEmail;
+ else
+ return false;
+ return true;
+ }
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StringSubstitutionStub);
+};
+
+} // namespace
+
+TEST(ONCStringExpansion, OpenVPN) {
+ scoped_ptr<base::DictionaryValue> vpn_onc =
+ test_utils::ReadTestDictionary("valid_openvpn.onc");
+
+ StringSubstitutionStub substitution;
+ ExpandStringsInOncObject(kNetworkConfigurationSignature, substitution,
+ vpn_onc.get());
+
+ std::string actual_expanded;
+ vpn_onc->GetString("VPN.OpenVPN.Username", &actual_expanded);
+ EXPECT_EQ(actual_expanded, std::string("abc ") + kLoginEmail + " def");
+}
+
+TEST(ONCStringExpansion, WiFi_EAP) {
+ scoped_ptr<base::DictionaryValue> wifi_onc =
+ test_utils::ReadTestDictionary("valid_wifi_clientcert.onc");
+
+ StringSubstitutionStub substitution;
+ ExpandStringsInOncObject(kNetworkConfigurationSignature, substitution,
+ wifi_onc.get());
+
+ std::string actual_expanded;
+ wifi_onc->GetString("WiFi.EAP.Identity", &actual_expanded);
+ EXPECT_EQ(actual_expanded, std::string("abc ") + kLoginId + "@my.domain.com");
+}
+
} // namespace onc
} // namespace chromeos