| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // The implementation of TranslateONCObjectToShill is structured in two parts: | 5 // The implementation of TranslateONCObjectToShill is structured in two parts: |
| 6 // - The recursion through the existing ONC hierarchy | 6 // - The recursion through the existing ONC hierarchy |
| 7 // see TranslateONCHierarchy | 7 // see TranslateONCHierarchy |
| 8 // - The local translation of an object depending on the associated signature | 8 // - The local translation of an object depending on the associated signature |
| 9 // see LocalTranslator::TranslateFields | 9 // see LocalTranslator::TranslateFields |
| 10 | 10 |
| 11 #include "chromeos/network/onc/onc_translator.h" | 11 #include "chromeos/network/onc/onc_translator.h" |
| 12 | 12 |
| 13 #include <string> | 13 #include <string> |
| 14 | 14 |
| 15 #include "base/json/json_reader.h" | 15 #include "base/json/json_reader.h" |
| 16 #include "base/json/json_writer.h" | 16 #include "base/json/json_writer.h" |
| 17 #include "base/logging.h" | 17 #include "base/logging.h" |
| 18 #include "base/values.h" | 18 #include "base/values.h" |
| 19 #include "chromeos/network/onc/onc_constants.h" | 19 #include "chromeos/network/onc/onc_constants.h" |
| 20 #include "chromeos/network/onc/onc_signature.h" | 20 #include "chromeos/network/onc/onc_signature.h" |
| 21 #include "chromeos/network/onc/onc_translation_tables.h" | 21 #include "chromeos/network/onc/onc_translation_tables.h" |
| 22 #include "third_party/cros_system_api/dbus/service_constants.h" | 22 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 23 | 23 |
| 24 namespace chromeos { | 24 namespace chromeos { |
| 25 namespace onc { | 25 namespace onc { |
| 26 | 26 |
| 27 namespace { | 27 namespace { |
| 28 | 28 |
| 29 scoped_ptr<base::ListValue> SingletonStringList(const std::string& str) { |
| 30 base::ListValue* list = new base::ListValue; |
| 31 list->AppendString(str); |
| 32 return make_scoped_ptr(list); |
| 33 } |
| 34 |
| 29 scoped_ptr<base::StringValue> ConvertValueToString(const base::Value& value) { | 35 scoped_ptr<base::StringValue> ConvertValueToString(const base::Value& value) { |
| 30 std::string str; | 36 std::string str; |
| 31 if (!value.GetAsString(&str)) | 37 if (!value.GetAsString(&str)) |
| 32 base::JSONWriter::Write(&value, &str); | 38 base::JSONWriter::Write(&value, &str); |
| 33 return make_scoped_ptr(base::Value::CreateStringValue(str)); | 39 return make_scoped_ptr(base::Value::CreateStringValue(str)); |
| 34 } | 40 } |
| 35 | 41 |
| 36 // This class is responsible to translate the local fields of the given | 42 // This class is responsible to translate the local fields of the given |
| 37 // |onc_object| according to |onc_signature| into |shill_dictionary|. This | 43 // |onc_object| according to |onc_signature| into |shill_dictionary|. This |
| 38 // translation should consider (if possible) only fields of this ONC object and | 44 // translation should consider (if possible) only fields of this ONC object and |
| 39 // not nested objects because recursion is handled by the calling function | 45 // not nested objects because recursion is handled by the calling function |
| 40 // TranslateONCHierarchy. | 46 // TranslateONCHierarchy. |
| 41 class LocalTranslator { | 47 class LocalTranslator { |
| 42 public: | 48 public: |
| 43 LocalTranslator(const OncValueSignature& onc_signature, | 49 LocalTranslator( |
| 44 const base::DictionaryValue& onc_object, | 50 const OncValueSignature& onc_signature, |
| 45 base::DictionaryValue* shill_dictionary) | 51 const base::DictionaryValue& onc_object, |
| 52 base::DictionaryValue* shill_dictionary, |
| 53 const FingerprintToPEM& fingerprint_to_pem) |
| 46 : onc_signature_(&onc_signature), | 54 : onc_signature_(&onc_signature), |
| 47 onc_object_(&onc_object), | 55 onc_object_(&onc_object), |
| 48 shill_dictionary_(shill_dictionary) { | 56 shill_dictionary_(shill_dictionary), |
| 57 fingerprint_to_pem_(fingerprint_to_pem) { |
| 49 field_translation_table_ = GetFieldTranslationTable(onc_signature); | 58 field_translation_table_ = GetFieldTranslationTable(onc_signature); |
| 50 } | 59 } |
| 51 | 60 |
| 52 void TranslateFields(); | 61 void TranslateFields(); |
| 53 | 62 |
| 54 private: | 63 private: |
| 55 void TranslateOpenVPN(); | 64 void TranslateOpenVPN(); |
| 65 void TranslateIPsec(); |
| 56 void TranslateVPN(); | 66 void TranslateVPN(); |
| 57 void TranslateWiFi(); | 67 void TranslateWiFi(); |
| 58 void TranslateEAP(); | 68 void TranslateEAP(); |
| 59 void TranslateNetworkConfiguration(); | 69 void TranslateNetworkConfiguration(); |
| 60 | 70 |
| 61 // Copies all entries from |onc_object_| to |shill_dictionary_| for which a | 71 // Copies all entries from |onc_object_| to |shill_dictionary_| for which a |
| 62 // translation (shill_property_name) is defined by |onc_signature_|. | 72 // translation (shill_property_name) is defined by |onc_signature_|. |
| 63 void CopyFieldsAccordingToSignature(); | 73 void CopyFieldsAccordingToSignature(); |
| 64 | 74 |
| 65 // Adds |value| to |shill_dictionary| at the field shill_property_name given | 75 // Adds |value| to |shill_dictionary| at the field shill_property_name given |
| 66 // by the associated signature. Takes ownership of |value|. Does nothing if | 76 // by the associated signature. Takes ownership of |value|. Does nothing if |
| 67 // |value| is NULL or the property name cannot be read from the signature. | 77 // |value| is NULL or the property name cannot be read from the signature. |
| 68 void AddValueAccordingToSignature(const std::string& onc_field_name, | 78 void AddValueAccordingToSignature(const std::string& onc_field_name, |
| 69 scoped_ptr<base::Value> value); | 79 scoped_ptr<base::Value> value); |
| 70 | 80 |
| 71 // If existent, translates the entry at |onc_field_name| in |onc_object_| | 81 // If existent, translates the entry at |onc_field_name| in |onc_object_| |
| 72 // using |table|. It is an error if no matching table entry is found. Writes | 82 // using |table|. It is an error if no matching table entry is found. Writes |
| 73 // the result as entry at |shill_property_name| in |shill_dictionary_|. | 83 // the result as entry at |shill_property_name| in |shill_dictionary_|. |
| 74 void TranslateWithTableAndSet(const std::string& onc_field_name, | 84 void TranslateWithTableAndSet(const std::string& onc_field_name, |
| 75 const StringTranslationEntry table[], | 85 const StringTranslationEntry table[], |
| 76 const std::string& shill_property_name); | 86 const std::string& shill_property_name); |
| 77 | 87 |
| 78 const OncValueSignature* onc_signature_; | 88 const OncValueSignature* onc_signature_; |
| 79 const FieldTranslationEntry* field_translation_table_; | 89 const FieldTranslationEntry* field_translation_table_; |
| 80 const base::DictionaryValue* onc_object_; | 90 const base::DictionaryValue* onc_object_; |
| 81 base::DictionaryValue* shill_dictionary_; | 91 base::DictionaryValue* shill_dictionary_; |
| 92 FingerprintToPEM fingerprint_to_pem_; |
| 82 | 93 |
| 83 DISALLOW_COPY_AND_ASSIGN(LocalTranslator); | 94 DISALLOW_COPY_AND_ASSIGN(LocalTranslator); |
| 84 }; | 95 }; |
| 85 | 96 |
| 86 void LocalTranslator::TranslateFields() { | 97 void LocalTranslator::TranslateFields() { |
| 87 if (onc_signature_ == &kNetworkConfigurationSignature) | 98 if (onc_signature_ == &kNetworkConfigurationSignature) |
| 88 TranslateNetworkConfiguration(); | 99 TranslateNetworkConfiguration(); |
| 89 else if (onc_signature_ == &kVPNSignature) | 100 else if (onc_signature_ == &kVPNSignature) |
| 90 TranslateVPN(); | 101 TranslateVPN(); |
| 91 else if (onc_signature_ == &kOpenVPNSignature) | 102 else if (onc_signature_ == &kOpenVPNSignature) |
| 92 TranslateOpenVPN(); | 103 TranslateOpenVPN(); |
| 104 else if (onc_signature_ == &kIPsecSignature) |
| 105 TranslateIPsec(); |
| 93 else if (onc_signature_ == &kWiFiSignature) | 106 else if (onc_signature_ == &kWiFiSignature) |
| 94 TranslateWiFi(); | 107 TranslateWiFi(); |
| 95 else if (onc_signature_ == &kEAPSignature) | 108 else if (onc_signature_ == &kEAPSignature) |
| 96 TranslateEAP(); | 109 TranslateEAP(); |
| 97 else | 110 else |
| 98 CopyFieldsAccordingToSignature(); | 111 CopyFieldsAccordingToSignature(); |
| 99 } | 112 } |
| 100 | 113 |
| 101 void LocalTranslator::TranslateOpenVPN() { | 114 void LocalTranslator::TranslateOpenVPN() { |
| 102 // Shill supports only one RemoteCertKU but ONC a list. | 115 // Shill supports only one RemoteCertKU but ONC a list. |
| 103 // Copy only the first entry if existing. | 116 // Copy only the first entry if existing. |
| 104 const base::ListValue* certKUs = NULL; | 117 const base::ListValue* cert_kus = NULL; |
| 105 std::string certKU; | 118 std::string cert_ku; |
| 106 if (onc_object_->GetListWithoutPathExpansion(vpn::kRemoteCertKU, &certKUs) && | 119 if (onc_object_->GetListWithoutPathExpansion(vpn::kRemoteCertKU, &cert_kus) && |
| 107 certKUs->GetString(0, &certKU)) { | 120 cert_kus->GetString(0, &cert_ku)) { |
| 108 shill_dictionary_->SetStringWithoutPathExpansion( | 121 shill_dictionary_->SetStringWithoutPathExpansion( |
| 109 flimflam::kOpenVPNRemoteCertKUProperty, certKU); | 122 flimflam::kOpenVPNRemoteCertKUProperty, cert_ku); |
| 123 } |
| 124 |
| 125 std::string ca_cert_fingerprint; |
| 126 if (onc_object_->GetStringWithoutPathExpansion(vpn::kServerCAFingerprint, |
| 127 &ca_cert_fingerprint)) { |
| 128 std::string ca_cert_pem = fingerprint_to_pem_.Run(ca_cert_fingerprint); |
| 129 if (!ca_cert_pem.empty()) { |
| 130 shill_dictionary_->SetWithoutPathExpansion( |
| 131 shill::kOpenVPNCaCertPemProperty, |
| 132 SingletonStringList(ca_cert_pem).release()); |
| 133 } |
| 110 } | 134 } |
| 111 | 135 |
| 112 for (base::DictionaryValue::Iterator it(*onc_object_); !it.IsAtEnd(); | 136 for (base::DictionaryValue::Iterator it(*onc_object_); !it.IsAtEnd(); |
| 113 it.Advance()) { | 137 it.Advance()) { |
| 114 scoped_ptr<base::Value> translated; | 138 scoped_ptr<base::Value> translated; |
| 115 if (it.key() == vpn::kSaveCredentials || it.key() == vpn::kRemoteCertKU) { | 139 if (it.key() == vpn::kSaveCredentials || it.key() == vpn::kRemoteCertKU) { |
| 116 translated.reset(it.value().DeepCopy()); | 140 translated.reset(it.value().DeepCopy()); |
| 117 } else { | 141 } else { |
| 118 // Shill wants all Provider/VPN fields to be strings. | 142 // Shill wants all Provider/VPN fields to be strings. |
| 119 translated = ConvertValueToString(it.value()); | 143 translated = ConvertValueToString(it.value()); |
| 120 } | 144 } |
| 121 AddValueAccordingToSignature(it.key(), translated.Pass()); | 145 AddValueAccordingToSignature(it.key(), translated.Pass()); |
| 122 } | 146 } |
| 123 } | 147 } |
| 124 | 148 |
| 149 void LocalTranslator::TranslateIPsec() { |
| 150 std::string ca_cert_fingerprint; |
| 151 if (onc_object_->GetStringWithoutPathExpansion(vpn::kServerCAFingerprint, |
| 152 &ca_cert_fingerprint)) { |
| 153 std::string ca_cert_pem = fingerprint_to_pem_.Run(ca_cert_fingerprint); |
| 154 if (!ca_cert_pem.empty()) { |
| 155 shill_dictionary_->SetWithoutPathExpansion( |
| 156 shill::kL2tpIpsecCaCertPemProperty, |
| 157 SingletonStringList(ca_cert_pem).release()); |
| 158 } |
| 159 } |
| 160 CopyFieldsAccordingToSignature(); |
| 161 } |
| 162 |
| 125 void LocalTranslator::TranslateVPN() { | 163 void LocalTranslator::TranslateVPN() { |
| 126 std::string type; | 164 std::string type; |
| 127 onc_object_->GetStringWithoutPathExpansion(vpn::kType, &type); | 165 onc_object_->GetStringWithoutPathExpansion(vpn::kType, &type); |
| 128 TranslateWithTableAndSet(type, kVPNTypeTable, | 166 TranslateWithTableAndSet(type, kVPNTypeTable, |
| 129 flimflam::kProviderTypeProperty); | 167 flimflam::kProviderTypeProperty); |
| 130 | 168 |
| 131 CopyFieldsAccordingToSignature(); | 169 CopyFieldsAccordingToSignature(); |
| 132 } | 170 } |
| 133 | 171 |
| 134 void LocalTranslator::TranslateWiFi() { | 172 void LocalTranslator::TranslateWiFi() { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 155 // ONC's Inner == "Automatic" translates to omitting the Phase2 property in | 193 // ONC's Inner == "Automatic" translates to omitting the Phase2 property in |
| 156 // Shill. | 194 // Shill. |
| 157 onc_object_->GetStringWithoutPathExpansion(eap::kInner, &inner); | 195 onc_object_->GetStringWithoutPathExpansion(eap::kInner, &inner); |
| 158 if (inner != eap::kAutomatic) { | 196 if (inner != eap::kAutomatic) { |
| 159 const StringTranslationEntry* table = | 197 const StringTranslationEntry* table = |
| 160 outer == eap::kPEAP ? kEAP_PEAP_InnerTable : kEAP_TTLS_InnerTable; | 198 outer == eap::kPEAP ? kEAP_PEAP_InnerTable : kEAP_TTLS_InnerTable; |
| 161 TranslateWithTableAndSet(inner, table, flimflam::kEapPhase2AuthProperty); | 199 TranslateWithTableAndSet(inner, table, flimflam::kEapPhase2AuthProperty); |
| 162 } | 200 } |
| 163 } | 201 } |
| 164 | 202 |
| 203 std::string ca_cert_fingerprint; |
| 204 if (onc_object_->GetStringWithoutPathExpansion(eap::kServerCAFingerprint, |
| 205 &ca_cert_fingerprint)) { |
| 206 std::string ca_cert_pem = fingerprint_to_pem_.Run(ca_cert_fingerprint); |
| 207 if (!ca_cert_pem.empty()) { |
| 208 shill_dictionary_->SetWithoutPathExpansion( |
| 209 shill::kEapCaCertPemProperty, |
| 210 SingletonStringList(ca_cert_pem).release()); |
| 211 } |
| 212 } |
| 213 |
| 165 CopyFieldsAccordingToSignature(); | 214 CopyFieldsAccordingToSignature(); |
| 166 } | 215 } |
| 167 | 216 |
| 168 void LocalTranslator::TranslateNetworkConfiguration() { | 217 void LocalTranslator::TranslateNetworkConfiguration() { |
| 169 std::string type; | 218 std::string type; |
| 170 onc_object_->GetStringWithoutPathExpansion(network_config::kType, &type); | 219 onc_object_->GetStringWithoutPathExpansion(network_config::kType, &type); |
| 171 TranslateWithTableAndSet(type, kNetworkTypeTable, flimflam::kTypeProperty); | 220 TranslateWithTableAndSet(type, kNetworkTypeTable, flimflam::kTypeProperty); |
| 172 | 221 |
| 173 // Shill doesn't allow setting the name for non-VPN networks. | 222 // Shill doesn't allow setting the name for non-VPN networks. |
| 174 if (type == network_type::kVPN) { | 223 if (type == network_type::kVPN) { |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 // occurs, we should check here. Otherwise the failure will only show up much | 268 // occurs, we should check here. Otherwise the failure will only show up much |
| 220 // later in Shill. | 269 // later in Shill. |
| 221 LOG(ERROR) << "Value '" << onc_value | 270 LOG(ERROR) << "Value '" << onc_value |
| 222 << "' cannot be translated to Shill property " | 271 << "' cannot be translated to Shill property " |
| 223 << shill_property_name; | 272 << shill_property_name; |
| 224 } | 273 } |
| 225 | 274 |
| 226 // Iterates recursively over |onc_object| and its |signature|. At each object | 275 // Iterates recursively over |onc_object| and its |signature|. At each object |
| 227 // applies the local translation using LocalTranslator::TranslateFields. The | 276 // applies the local translation using LocalTranslator::TranslateFields. The |
| 228 // results are written to |shill_dictionary|. | 277 // results are written to |shill_dictionary|. |
| 229 void TranslateONCHierarchy(const OncValueSignature& signature, | 278 void TranslateONCHierarchy( |
| 230 const base::DictionaryValue& onc_object, | 279 const OncValueSignature& signature, |
| 231 base::DictionaryValue* shill_dictionary) { | 280 const base::DictionaryValue& onc_object, |
| 281 const FingerprintToPEM& fingerprint_to_pem, |
| 282 base::DictionaryValue* shill_dictionary) { |
| 232 // Translates fields of |onc_object| and writes them to |shill_dictionary_|. | 283 // Translates fields of |onc_object| and writes them to |shill_dictionary_|. |
| 233 LocalTranslator translator(signature, onc_object, shill_dictionary); | 284 LocalTranslator translator(signature, onc_object, shill_dictionary, |
| 285 fingerprint_to_pem); |
| 234 translator.TranslateFields(); | 286 translator.TranslateFields(); |
| 235 | 287 |
| 236 // Recurse into nested objects. | 288 // Recurse into nested objects. |
| 237 for (base::DictionaryValue::Iterator it(onc_object); !it.IsAtEnd(); | 289 for (base::DictionaryValue::Iterator it(onc_object); !it.IsAtEnd(); |
| 238 it.Advance()) { | 290 it.Advance()) { |
| 239 const base::DictionaryValue* inner_object = NULL; | 291 const base::DictionaryValue* inner_object = NULL; |
| 240 if (!it.value().GetAsDictionary(&inner_object)) | 292 if (!it.value().GetAsDictionary(&inner_object)) |
| 241 continue; | 293 continue; |
| 242 | 294 |
| 243 const OncFieldSignature* field_signature = | 295 const OncFieldSignature* field_signature = |
| 244 GetFieldSignature(signature, it.key()); | 296 GetFieldSignature(signature, it.key()); |
| 245 | 297 |
| 246 TranslateONCHierarchy(*field_signature->value_signature, *inner_object, | 298 TranslateONCHierarchy(*field_signature->value_signature, *inner_object, |
| 247 shill_dictionary); | 299 fingerprint_to_pem, shill_dictionary); |
| 248 } | 300 } |
| 249 } | 301 } |
| 250 | 302 |
| 251 } // namespace | 303 } // namespace |
| 252 | 304 |
| 253 scoped_ptr<base::DictionaryValue> TranslateONCObjectToShill( | 305 scoped_ptr<base::DictionaryValue> TranslateONCObjectToShill( |
| 254 const OncValueSignature* onc_signature, | 306 const OncValueSignature* onc_signature, |
| 255 const base::DictionaryValue& onc_object) { | 307 const base::DictionaryValue& onc_object, |
| 308 const FingerprintToPEM& fingerprint_to_pem) { |
| 256 CHECK(onc_signature != NULL); | 309 CHECK(onc_signature != NULL); |
| 257 scoped_ptr<base::DictionaryValue> shill_dictionary(new base::DictionaryValue); | 310 scoped_ptr<base::DictionaryValue> shill_dictionary(new base::DictionaryValue); |
| 258 TranslateONCHierarchy(*onc_signature, onc_object, shill_dictionary.get()); | 311 TranslateONCHierarchy(*onc_signature, onc_object, fingerprint_to_pem, |
| 312 shill_dictionary.get()); |
| 259 return shill_dictionary.Pass(); | 313 return shill_dictionary.Pass(); |
| 260 } | 314 } |
| 261 | 315 |
| 262 } // namespace onc | 316 } // namespace onc |
| 263 } // namespace chromeos | 317 } // namespace chromeos |
| OLD | NEW |