Chromium Code Reviews| 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 #include "chromeos/network/onc/onc_translator.h" | 5 #include "chromeos/network/onc/onc_translator.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 // associated to |onc_field_name| and adds it to |onc_object_| at | 82 // associated to |onc_field_name| and adds it to |onc_object_| at |
| 83 // |onc_field_name|. | 83 // |onc_field_name|. |
| 84 void TranslateAndAddNestedObject(const std::string& onc_field_name, | 84 void TranslateAndAddNestedObject(const std::string& onc_field_name, |
| 85 const base::DictionaryValue& dictionary); | 85 const base::DictionaryValue& dictionary); |
| 86 | 86 |
| 87 // Creates an ONC object from |shill_dictionary_| according to the signature | 87 // Creates an ONC object from |shill_dictionary_| according to the signature |
| 88 // associated to |onc_field_name| and adds it to |onc_object_| at | 88 // associated to |onc_field_name| and adds it to |onc_object_| at |
| 89 // |onc_field_name|. | 89 // |onc_field_name|. |
| 90 void TranslateAndAddNestedObject(const std::string& onc_field_name); | 90 void TranslateAndAddNestedObject(const std::string& onc_field_name); |
| 91 | 91 |
| 92 // Sets |onc_field_name| in dictionary |onc_dictionary_name| in |onc_object_| | |
| 93 // to |value| if the dictionary exists. | |
| 94 void SetNestedOncValue(const std::string& onc_dictionary_name, | |
| 95 const std::string& onc_field_name, | |
| 96 const base::Value& value); | |
| 97 | |
| 92 // Translates a list of nested objects and adds the list to |onc_object_| at | 98 // Translates a list of nested objects and adds the list to |onc_object_| at |
| 93 // |onc_field_name|. If there are errors while parsing individual objects or | 99 // |onc_field_name|. If there are errors while parsing individual objects or |
| 94 // if the resulting list contains no entries, the result will not be added to | 100 // if the resulting list contains no entries, the result will not be added to |
| 95 // |onc_object_|. | 101 // |onc_object_|. |
| 96 void TranslateAndAddListOfObjects(const std::string& onc_field_name, | 102 void TranslateAndAddListOfObjects(const std::string& onc_field_name, |
| 97 const base::ListValue& list); | 103 const base::ListValue& list); |
| 98 | 104 |
| 99 // Applies function CopyProperty to each field of |value_signature| and its | 105 // Applies function CopyProperty to each field of |value_signature| and its |
| 100 // base signatures. | 106 // base signatures. |
| 101 void CopyPropertiesAccordingToSignature( | 107 void CopyPropertiesAccordingToSignature( |
| 102 const OncValueSignature* value_signature); | 108 const OncValueSignature* value_signature); |
| 103 | 109 |
| 104 // Applies function CopyProperty to each field of |onc_signature_| and its | 110 // Applies function CopyProperty to each field of |onc_signature_| and its |
| 105 // base signatures. | 111 // base signatures. |
| 106 void CopyPropertiesAccordingToSignature(); | 112 void CopyPropertiesAccordingToSignature(); |
| 107 | 113 |
| 108 // If |shill_property_name| is defined in |field_signature|, copies this | 114 // If |shill_property_name| is defined in |field_signature|, copies this |
| 109 // entry from |shill_dictionary_| to |onc_object_| if it exists. | 115 // entry from |shill_dictionary_| to |onc_object_| if it exists. |
| 110 void CopyProperty(const OncFieldSignature* field_signature); | 116 void CopyProperty(const OncFieldSignature* field_signature); |
| 111 | 117 |
| 112 // If existent, translates the entry at |shill_property_name| in | 118 // If existent, translates the entry at |shill_property_name| in |
| 113 // |shill_dictionary_| using |table|. It is an error if no matching table | 119 // |shill_dictionary_| using |table|. It is an error if no matching table |
| 114 // entry is found. Writes the result as entry at |onc_field_name| in | 120 // entry is found. Writes the result as entry at |onc_field_name| in |
| 115 // |onc_object_|. | 121 // |onc_object_|. |
| 116 void TranslateWithTableAndSet(const std::string& shill_property_name, | 122 void TranslateWithTableAndSet(const std::string& shill_property_name, |
| 117 const StringTranslationEntry table[], | 123 const StringTranslationEntry table[], |
| 118 const std::string& onc_field_name); | 124 const std::string& onc_field_name); |
| 119 | 125 |
| 126 // Returns the name provided in |shill_dictionary_| for debugging. | |
|
pneubeck (no reviews)
2014/08/20 19:49:36
nit: 'name' -> 'name of the Shill Service'
stevenjb
2014/08/20 20:40:04
Done.
| |
| 127 std::string GetName(); | |
| 128 | |
| 120 const base::DictionaryValue* shill_dictionary_; | 129 const base::DictionaryValue* shill_dictionary_; |
| 121 const OncValueSignature* onc_signature_; | 130 const OncValueSignature* onc_signature_; |
| 122 const FieldTranslationEntry* field_translation_table_; | 131 const FieldTranslationEntry* field_translation_table_; |
| 123 scoped_ptr<base::DictionaryValue> onc_object_; | 132 scoped_ptr<base::DictionaryValue> onc_object_; |
| 124 | 133 |
| 125 DISALLOW_COPY_AND_ASSIGN(ShillToONCTranslator); | 134 DISALLOW_COPY_AND_ASSIGN(ShillToONCTranslator); |
| 126 }; | 135 }; |
| 127 | 136 |
| 128 scoped_ptr<base::DictionaryValue> | 137 scoped_ptr<base::DictionaryValue> |
| 129 ShillToONCTranslator::CreateTranslatedONCObject() { | 138 ShillToONCTranslator::CreateTranslatedONCObject() { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 shill::kOpenVPNRemoteCertKUProperty, &certKU)) { | 184 shill::kOpenVPNRemoteCertKUProperty, &certKU)) { |
| 176 scoped_ptr<base::ListValue> certKUs(new base::ListValue); | 185 scoped_ptr<base::ListValue> certKUs(new base::ListValue); |
| 177 certKUs->AppendString(certKU); | 186 certKUs->AppendString(certKU); |
| 178 onc_object_->SetWithoutPathExpansion(::onc::openvpn::kRemoteCertKU, | 187 onc_object_->SetWithoutPathExpansion(::onc::openvpn::kRemoteCertKU, |
| 179 certKUs.release()); | 188 certKUs.release()); |
| 180 } | 189 } |
| 181 | 190 |
| 182 for (const OncFieldSignature* field_signature = onc_signature_->fields; | 191 for (const OncFieldSignature* field_signature = onc_signature_->fields; |
| 183 field_signature->onc_field_name != NULL; ++field_signature) { | 192 field_signature->onc_field_name != NULL; ++field_signature) { |
| 184 const std::string& onc_field_name = field_signature->onc_field_name; | 193 const std::string& onc_field_name = field_signature->onc_field_name; |
| 185 if (onc_field_name == ::onc::vpn::kSaveCredentials || | 194 if (onc_field_name == ::onc::openvpn::kRemoteCertKU || |
| 186 onc_field_name == ::onc::openvpn::kRemoteCertKU || | |
| 187 onc_field_name == ::onc::openvpn::kServerCAPEMs) { | 195 onc_field_name == ::onc::openvpn::kServerCAPEMs) { |
| 188 CopyProperty(field_signature); | 196 CopyProperty(field_signature); |
| 189 continue; | 197 continue; |
| 190 } | 198 } |
| 191 | 199 |
| 192 std::string shill_property_name; | 200 std::string shill_property_name; |
| 193 const base::Value* shill_value = NULL; | 201 const base::Value* shill_value = NULL; |
| 194 if (!field_translation_table_ || | 202 if (!field_translation_table_ || |
| 195 !GetShillPropertyName(field_signature->onc_field_name, | 203 !GetShillPropertyName(field_signature->onc_field_name, |
| 196 field_translation_table_, | 204 field_translation_table_, |
| 197 &shill_property_name) || | 205 &shill_property_name) || |
| 198 !shill_dictionary_->GetWithoutPathExpansion(shill_property_name, | 206 !shill_dictionary_->GetWithoutPathExpansion(shill_property_name, |
| 199 &shill_value)) { | 207 &shill_value)) { |
| 200 continue; | 208 continue; |
| 201 } | 209 } |
| 202 | 210 |
| 203 scoped_ptr<base::Value> translated; | 211 scoped_ptr<base::Value> translated; |
| 204 std::string shill_str; | 212 std::string shill_str; |
| 205 if (shill_value->GetAsString(&shill_str)) { | 213 if (shill_value->GetAsString(&shill_str)) { |
| 206 // Shill wants all Provider/VPN fields to be strings. Translates these | 214 // Shill wants all Provider/VPN fields to be strings. Translates these |
| 207 // strings back to the correct ONC type. | 215 // strings back to the correct ONC type. |
| 208 translated = ConvertStringToValue( | 216 translated = ConvertStringToValue( |
| 209 shill_str, | 217 shill_str, |
| 210 field_signature->value_signature->onc_type); | 218 field_signature->value_signature->onc_type); |
| 211 | 219 |
| 212 if (translated.get() == NULL) { | 220 if (translated.get() == NULL) { |
| 213 LOG(ERROR) << "Shill property '" << shill_property_name | 221 LOG(ERROR) << "Shill property '" << shill_property_name |
| 214 << "' with value " << *shill_value | 222 << "' with value " << *shill_value |
| 215 << " couldn't be converted to base::Value::Type " | 223 << " couldn't be converted to base::Value::Type " |
| 216 << field_signature->value_signature->onc_type; | 224 << field_signature->value_signature->onc_type |
| 225 << ": " << GetName(); | |
| 217 } else { | 226 } else { |
| 218 onc_object_->SetWithoutPathExpansion(onc_field_name, | 227 onc_object_->SetWithoutPathExpansion(onc_field_name, |
| 219 translated.release()); | 228 translated.release()); |
| 220 } | 229 } |
| 221 } else { | 230 } else { |
| 222 LOG(ERROR) << "Shill property '" << shill_property_name | 231 LOG(ERROR) << "Shill property '" << shill_property_name |
| 223 << "' has value " << *shill_value | 232 << "' has value " << *shill_value |
| 224 << ", but expected a string"; | 233 << ", but expected a string: " << GetName(); |
| 225 } | 234 } |
| 226 } | 235 } |
| 227 } | 236 } |
| 228 | 237 |
| 229 void ShillToONCTranslator::TranslateIPsec() { | 238 void ShillToONCTranslator::TranslateIPsec() { |
| 230 CopyPropertiesAccordingToSignature(); | 239 CopyPropertiesAccordingToSignature(); |
| 231 if (shill_dictionary_->HasKey(shill::kL2tpIpsecXauthUserProperty)) | 240 if (shill_dictionary_->HasKey(shill::kL2tpIpsecXauthUserProperty)) |
| 232 TranslateAndAddNestedObject(::onc::ipsec::kXAUTH); | 241 TranslateAndAddNestedObject(::onc::ipsec::kXAUTH); |
| 233 } | 242 } |
| 234 | 243 |
| 235 void ShillToONCTranslator::TranslateVPN() { | 244 void ShillToONCTranslator::TranslateVPN() { |
| 236 TranslateWithTableAndSet( | |
| 237 shill::kProviderTypeProperty, kVPNTypeTable, ::onc::vpn::kType); | |
| 238 CopyPropertiesAccordingToSignature(); | 245 CopyPropertiesAccordingToSignature(); |
| 239 | 246 |
| 240 std::string vpn_type; | 247 // Parse Shill Provider dictionary. Note, this may not exist, e.g. if we are |
| 241 if (onc_object_->GetStringWithoutPathExpansion(::onc::vpn::kType, | 248 // just translating network state in network_util::TranslateNetworkStateToONC. |
| 242 &vpn_type)) { | 249 const base::DictionaryValue* provider = NULL; |
| 243 if (vpn_type == ::onc::vpn::kTypeL2TP_IPsec) { | 250 if (!shill_dictionary_->GetDictionaryWithoutPathExpansion( |
| 244 TranslateAndAddNestedObject(::onc::vpn::kIPsec); | 251 shill::kProviderProperty, &provider)) { |
| 245 TranslateAndAddNestedObject(::onc::vpn::kL2TP); | 252 return; |
| 246 } else { | 253 } |
| 247 TranslateAndAddNestedObject(vpn_type); | 254 std::string shill_provider_type, onc_provider_type; |
| 248 } | 255 provider->GetStringWithoutPathExpansion(shill::kTypeProperty, |
| 256 &shill_provider_type); | |
| 257 if (!TranslateStringToONC( | |
| 258 kVPNTypeTable, shill_provider_type, &onc_provider_type)) { | |
| 259 return; | |
| 260 } | |
| 261 onc_object_->SetStringWithoutPathExpansion(::onc::vpn::kType, | |
| 262 onc_provider_type); | |
| 263 std::string provider_host; | |
| 264 if (provider->GetStringWithoutPathExpansion(shill::kHostProperty, | |
| 265 &provider_host)) { | |
| 266 onc_object_->SetStringWithoutPathExpansion(::onc::vpn::kHost, | |
| 267 provider_host); | |
| 268 } | |
| 269 | |
| 270 // Translate the nested dictionary. | |
| 271 std::string provider_type_dictionary; | |
| 272 if (onc_provider_type == ::onc::vpn::kTypeL2TP_IPsec) { | |
| 273 TranslateAndAddNestedObject(::onc::vpn::kIPsec, *provider); | |
| 274 TranslateAndAddNestedObject(::onc::vpn::kL2TP, *provider); | |
| 275 provider_type_dictionary = ::onc::vpn::kIPsec; | |
| 276 } else { | |
| 277 TranslateAndAddNestedObject(onc_provider_type, *provider); | |
| 278 provider_type_dictionary = onc_provider_type; | |
| 279 } | |
| 280 | |
| 281 bool save_credentials; | |
| 282 if (shill_dictionary_->GetBooleanWithoutPathExpansion( | |
| 283 shill::kSaveCredentialsProperty, &save_credentials)) { | |
| 284 SetNestedOncValue(provider_type_dictionary, | |
| 285 ::onc::vpn::kSaveCredentials, | |
| 286 base::FundamentalValue(save_credentials)); | |
| 249 } | 287 } |
| 250 } | 288 } |
| 251 | 289 |
| 252 void ShillToONCTranslator::TranslateWiFiWithState() { | 290 void ShillToONCTranslator::TranslateWiFiWithState() { |
| 253 TranslateWithTableAndSet( | 291 TranslateWithTableAndSet( |
| 254 shill::kSecurityProperty, kWiFiSecurityTable, ::onc::wifi::kSecurity); | 292 shill::kSecurityProperty, kWiFiSecurityTable, ::onc::wifi::kSecurity); |
| 255 std::string ssid = shill_property_util::GetSSIDFromProperties( | 293 std::string ssid = shill_property_util::GetSSIDFromProperties( |
| 256 *shill_dictionary_, NULL /* ignore unknown encoding */); | 294 *shill_dictionary_, NULL /* ignore unknown encoding */); |
| 257 if (!ssid.empty()) | 295 if (!ssid.empty()) |
| 258 onc_object_->SetStringWithoutPathExpansion(::onc::wifi::kSSID, ssid); | 296 onc_object_->SetStringWithoutPathExpansion(::onc::wifi::kSSID, ssid); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 404 } | 442 } |
| 405 ShillToONCTranslator nested_translator(dictionary, | 443 ShillToONCTranslator nested_translator(dictionary, |
| 406 *field_signature->value_signature); | 444 *field_signature->value_signature); |
| 407 scoped_ptr<base::DictionaryValue> nested_object = | 445 scoped_ptr<base::DictionaryValue> nested_object = |
| 408 nested_translator.CreateTranslatedONCObject(); | 446 nested_translator.CreateTranslatedONCObject(); |
| 409 if (nested_object->empty()) | 447 if (nested_object->empty()) |
| 410 return; | 448 return; |
| 411 onc_object_->SetWithoutPathExpansion(onc_field_name, nested_object.release()); | 449 onc_object_->SetWithoutPathExpansion(onc_field_name, nested_object.release()); |
| 412 } | 450 } |
| 413 | 451 |
| 452 void ShillToONCTranslator::SetNestedOncValue( | |
| 453 const std::string& onc_dictionary_name, | |
| 454 const std::string& onc_field_name, | |
| 455 const base::Value& value) { | |
| 456 base::DictionaryValue* nested; | |
| 457 if (!onc_object_->GetDictionaryWithoutPathExpansion( | |
| 458 onc_dictionary_name, &nested)) { | |
| 459 nested = new base::DictionaryValue; | |
| 460 onc_object_->SetWithoutPathExpansion(onc_dictionary_name, nested); | |
| 461 } | |
| 462 nested->SetWithoutPathExpansion(onc_field_name, value.DeepCopy()); | |
| 463 } | |
| 464 | |
| 414 void ShillToONCTranslator::TranslateAndAddListOfObjects( | 465 void ShillToONCTranslator::TranslateAndAddListOfObjects( |
| 415 const std::string& onc_field_name, | 466 const std::string& onc_field_name, |
| 416 const base::ListValue& list) { | 467 const base::ListValue& list) { |
| 417 const OncFieldSignature* field_signature = | 468 const OncFieldSignature* field_signature = |
| 418 GetFieldSignature(*onc_signature_, onc_field_name); | 469 GetFieldSignature(*onc_signature_, onc_field_name); |
| 419 if (field_signature->value_signature->onc_type != base::Value::TYPE_LIST) { | 470 if (field_signature->value_signature->onc_type != base::Value::TYPE_LIST) { |
| 420 LOG(ERROR) << "ONC Field name: '" << onc_field_name << "' has type '" | 471 LOG(ERROR) << "ONC Field name: '" << onc_field_name << "' has type '" |
| 421 << field_signature->value_signature->onc_type | 472 << field_signature->value_signature->onc_type |
| 422 << "', expected: base::Value::TYPE_LIST."; | 473 << "', expected: base::Value::TYPE_LIST: " << GetName(); |
| 423 return; | 474 return; |
| 424 } | 475 } |
| 425 DCHECK(field_signature->value_signature->onc_array_entry_signature); | 476 DCHECK(field_signature->value_signature->onc_array_entry_signature); |
| 426 scoped_ptr<base::ListValue> result(new base::ListValue()); | 477 scoped_ptr<base::ListValue> result(new base::ListValue()); |
| 427 for (base::ListValue::const_iterator it = list.begin(); | 478 for (base::ListValue::const_iterator it = list.begin(); |
| 428 it != list.end(); ++it) { | 479 it != list.end(); ++it) { |
| 429 const base::DictionaryValue* shill_value = NULL; | 480 const base::DictionaryValue* shill_value = NULL; |
| 430 if (!(*it)->GetAsDictionary(&shill_value)) | 481 if (!(*it)->GetAsDictionary(&shill_value)) |
| 431 continue; | 482 continue; |
| 432 ShillToONCTranslator nested_translator( | 483 ShillToONCTranslator nested_translator( |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 471 &shill_value)) { | 522 &shill_value)) { |
| 472 return; | 523 return; |
| 473 } | 524 } |
| 474 | 525 |
| 475 if (shill_value->GetType() != field_signature->value_signature->onc_type) { | 526 if (shill_value->GetType() != field_signature->value_signature->onc_type) { |
| 476 LOG(ERROR) << "Shill property '" << shill_property_name | 527 LOG(ERROR) << "Shill property '" << shill_property_name |
| 477 << "' with value " << *shill_value | 528 << "' with value " << *shill_value |
| 478 << " has base::Value::Type " << shill_value->GetType() | 529 << " has base::Value::Type " << shill_value->GetType() |
| 479 << " but ONC field '" << field_signature->onc_field_name | 530 << " but ONC field '" << field_signature->onc_field_name |
| 480 << "' requires type " | 531 << "' requires type " |
| 481 << field_signature->value_signature->onc_type << "."; | 532 << field_signature->value_signature->onc_type |
| 533 << ": " << GetName(); | |
| 482 return; | 534 return; |
| 483 } | 535 } |
| 484 | 536 |
| 485 onc_object_->SetWithoutPathExpansion(field_signature->onc_field_name, | 537 onc_object_->SetWithoutPathExpansion(field_signature->onc_field_name, |
| 486 shill_value->DeepCopy()); | 538 shill_value->DeepCopy()); |
| 487 } | 539 } |
| 488 | 540 |
| 489 void ShillToONCTranslator::TranslateWithTableAndSet( | 541 void ShillToONCTranslator::TranslateWithTableAndSet( |
| 490 const std::string& shill_property_name, | 542 const std::string& shill_property_name, |
| 491 const StringTranslationEntry table[], | 543 const StringTranslationEntry table[], |
| 492 const std::string& onc_field_name) { | 544 const std::string& onc_field_name) { |
| 493 std::string shill_value; | 545 std::string shill_value; |
| 494 if (!shill_dictionary_->GetStringWithoutPathExpansion(shill_property_name, | 546 if (!shill_dictionary_->GetStringWithoutPathExpansion(shill_property_name, |
| 495 &shill_value)) { | 547 &shill_value)) { |
| 496 return; | 548 return; |
| 497 } | 549 } |
| 498 std::string onc_value; | 550 std::string onc_value; |
| 499 if (TranslateStringToONC(table, shill_value, &onc_value)) { | 551 if (TranslateStringToONC(table, shill_value, &onc_value)) { |
| 500 onc_object_->SetStringWithoutPathExpansion(onc_field_name, onc_value); | 552 onc_object_->SetStringWithoutPathExpansion(onc_field_name, onc_value); |
| 501 return; | 553 return; |
| 502 } | 554 } |
| 503 LOG(ERROR) << "Shill property '" << shill_property_name << "' with value " | 555 LOG(ERROR) << "Shill property '" << shill_property_name << "' with value " |
| 504 << shill_value << " couldn't be translated to ONC"; | 556 << shill_value << " couldn't be translated to ONC: " << GetName(); |
| 557 } | |
| 558 | |
| 559 std::string ShillToONCTranslator::GetName() { | |
| 560 if (!shill_dictionary_) | |
|
pneubeck (no reviews)
2014/08/20 19:49:36
optional nit: DCHECK
(the constructors don't allow
stevenjb
2014/08/20 20:40:04
Done.
| |
| 561 return "<no dictionary>"; | |
| 562 std::string name; | |
| 563 shill_dictionary_->GetStringWithoutPathExpansion(shill::kNameProperty, &name); | |
| 564 return name; | |
| 505 } | 565 } |
| 506 | 566 |
| 507 } // namespace | 567 } // namespace |
| 508 | 568 |
| 509 scoped_ptr<base::DictionaryValue> TranslateShillServiceToONCPart( | 569 scoped_ptr<base::DictionaryValue> TranslateShillServiceToONCPart( |
| 510 const base::DictionaryValue& shill_dictionary, | 570 const base::DictionaryValue& shill_dictionary, |
| 511 const OncValueSignature* onc_signature) { | 571 const OncValueSignature* onc_signature) { |
| 512 CHECK(onc_signature != NULL); | 572 CHECK(onc_signature != NULL); |
| 513 | 573 |
| 514 ShillToONCTranslator translator(shill_dictionary, *onc_signature); | 574 ShillToONCTranslator translator(shill_dictionary, *onc_signature); |
| 515 return translator.CreateTranslatedONCObject(); | 575 return translator.CreateTranslatedONCObject(); |
| 516 } | 576 } |
| 517 | 577 |
| 518 } // namespace onc | 578 } // namespace onc |
| 519 } // namespace chromeos | 579 } // namespace chromeos |
| OLD | NEW |