| 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 of the Shill service provided in |shill_dictionary_| |
| 127 // for debugging. |
| 128 std::string GetName(); |
| 129 |
| 120 const base::DictionaryValue* shill_dictionary_; | 130 const base::DictionaryValue* shill_dictionary_; |
| 121 const OncValueSignature* onc_signature_; | 131 const OncValueSignature* onc_signature_; |
| 122 const FieldTranslationEntry* field_translation_table_; | 132 const FieldTranslationEntry* field_translation_table_; |
| 123 scoped_ptr<base::DictionaryValue> onc_object_; | 133 scoped_ptr<base::DictionaryValue> onc_object_; |
| 124 | 134 |
| 125 DISALLOW_COPY_AND_ASSIGN(ShillToONCTranslator); | 135 DISALLOW_COPY_AND_ASSIGN(ShillToONCTranslator); |
| 126 }; | 136 }; |
| 127 | 137 |
| 128 scoped_ptr<base::DictionaryValue> | 138 scoped_ptr<base::DictionaryValue> |
| 129 ShillToONCTranslator::CreateTranslatedONCObject() { | 139 ShillToONCTranslator::CreateTranslatedONCObject() { |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 shill::kOpenVPNRemoteCertKUProperty, &certKU)) { | 185 shill::kOpenVPNRemoteCertKUProperty, &certKU)) { |
| 176 scoped_ptr<base::ListValue> certKUs(new base::ListValue); | 186 scoped_ptr<base::ListValue> certKUs(new base::ListValue); |
| 177 certKUs->AppendString(certKU); | 187 certKUs->AppendString(certKU); |
| 178 onc_object_->SetWithoutPathExpansion(::onc::openvpn::kRemoteCertKU, | 188 onc_object_->SetWithoutPathExpansion(::onc::openvpn::kRemoteCertKU, |
| 179 certKUs.release()); | 189 certKUs.release()); |
| 180 } | 190 } |
| 181 | 191 |
| 182 for (const OncFieldSignature* field_signature = onc_signature_->fields; | 192 for (const OncFieldSignature* field_signature = onc_signature_->fields; |
| 183 field_signature->onc_field_name != NULL; ++field_signature) { | 193 field_signature->onc_field_name != NULL; ++field_signature) { |
| 184 const std::string& onc_field_name = field_signature->onc_field_name; | 194 const std::string& onc_field_name = field_signature->onc_field_name; |
| 185 if (onc_field_name == ::onc::vpn::kSaveCredentials || | 195 if (onc_field_name == ::onc::openvpn::kRemoteCertKU || |
| 186 onc_field_name == ::onc::openvpn::kRemoteCertKU || | |
| 187 onc_field_name == ::onc::openvpn::kServerCAPEMs) { | 196 onc_field_name == ::onc::openvpn::kServerCAPEMs) { |
| 188 CopyProperty(field_signature); | 197 CopyProperty(field_signature); |
| 189 continue; | 198 continue; |
| 190 } | 199 } |
| 191 | 200 |
| 192 std::string shill_property_name; | 201 std::string shill_property_name; |
| 193 const base::Value* shill_value = NULL; | 202 const base::Value* shill_value = NULL; |
| 194 if (!field_translation_table_ || | 203 if (!field_translation_table_ || |
| 195 !GetShillPropertyName(field_signature->onc_field_name, | 204 !GetShillPropertyName(field_signature->onc_field_name, |
| 196 field_translation_table_, | 205 field_translation_table_, |
| 197 &shill_property_name) || | 206 &shill_property_name) || |
| 198 !shill_dictionary_->GetWithoutPathExpansion(shill_property_name, | 207 !shill_dictionary_->GetWithoutPathExpansion(shill_property_name, |
| 199 &shill_value)) { | 208 &shill_value)) { |
| 200 continue; | 209 continue; |
| 201 } | 210 } |
| 202 | 211 |
| 203 scoped_ptr<base::Value> translated; | 212 scoped_ptr<base::Value> translated; |
| 204 std::string shill_str; | 213 std::string shill_str; |
| 205 if (shill_value->GetAsString(&shill_str)) { | 214 if (shill_value->GetAsString(&shill_str)) { |
| 206 // Shill wants all Provider/VPN fields to be strings. Translates these | 215 // Shill wants all Provider/VPN fields to be strings. Translates these |
| 207 // strings back to the correct ONC type. | 216 // strings back to the correct ONC type. |
| 208 translated = ConvertStringToValue( | 217 translated = ConvertStringToValue( |
| 209 shill_str, | 218 shill_str, |
| 210 field_signature->value_signature->onc_type); | 219 field_signature->value_signature->onc_type); |
| 211 | 220 |
| 212 if (translated.get() == NULL) { | 221 if (translated.get() == NULL) { |
| 213 LOG(ERROR) << "Shill property '" << shill_property_name | 222 LOG(ERROR) << "Shill property '" << shill_property_name |
| 214 << "' with value " << *shill_value | 223 << "' with value " << *shill_value |
| 215 << " couldn't be converted to base::Value::Type " | 224 << " couldn't be converted to base::Value::Type " |
| 216 << field_signature->value_signature->onc_type; | 225 << field_signature->value_signature->onc_type |
| 226 << ": " << GetName(); |
| 217 } else { | 227 } else { |
| 218 onc_object_->SetWithoutPathExpansion(onc_field_name, | 228 onc_object_->SetWithoutPathExpansion(onc_field_name, |
| 219 translated.release()); | 229 translated.release()); |
| 220 } | 230 } |
| 221 } else { | 231 } else { |
| 222 LOG(ERROR) << "Shill property '" << shill_property_name | 232 LOG(ERROR) << "Shill property '" << shill_property_name |
| 223 << "' has value " << *shill_value | 233 << "' has value " << *shill_value |
| 224 << ", but expected a string"; | 234 << ", but expected a string: " << GetName(); |
| 225 } | 235 } |
| 226 } | 236 } |
| 227 } | 237 } |
| 228 | 238 |
| 229 void ShillToONCTranslator::TranslateIPsec() { | 239 void ShillToONCTranslator::TranslateIPsec() { |
| 230 CopyPropertiesAccordingToSignature(); | 240 CopyPropertiesAccordingToSignature(); |
| 231 if (shill_dictionary_->HasKey(shill::kL2tpIpsecXauthUserProperty)) | 241 if (shill_dictionary_->HasKey(shill::kL2tpIpsecXauthUserProperty)) |
| 232 TranslateAndAddNestedObject(::onc::ipsec::kXAUTH); | 242 TranslateAndAddNestedObject(::onc::ipsec::kXAUTH); |
| 233 } | 243 } |
| 234 | 244 |
| 235 void ShillToONCTranslator::TranslateVPN() { | 245 void ShillToONCTranslator::TranslateVPN() { |
| 236 TranslateWithTableAndSet( | |
| 237 shill::kProviderTypeProperty, kVPNTypeTable, ::onc::vpn::kType); | |
| 238 CopyPropertiesAccordingToSignature(); | 246 CopyPropertiesAccordingToSignature(); |
| 239 | 247 |
| 240 std::string vpn_type; | 248 // Parse Shill Provider dictionary. Note, this may not exist, e.g. if we are |
| 241 if (onc_object_->GetStringWithoutPathExpansion(::onc::vpn::kType, | 249 // just translating network state in network_util::TranslateNetworkStateToONC. |
| 242 &vpn_type)) { | 250 const base::DictionaryValue* provider = NULL; |
| 243 if (vpn_type == ::onc::vpn::kTypeL2TP_IPsec) { | 251 if (!shill_dictionary_->GetDictionaryWithoutPathExpansion( |
| 244 TranslateAndAddNestedObject(::onc::vpn::kIPsec); | 252 shill::kProviderProperty, &provider)) { |
| 245 TranslateAndAddNestedObject(::onc::vpn::kL2TP); | 253 return; |
| 246 } else { | 254 } |
| 247 TranslateAndAddNestedObject(vpn_type); | 255 std::string shill_provider_type, onc_provider_type; |
| 248 } | 256 provider->GetStringWithoutPathExpansion(shill::kTypeProperty, |
| 257 &shill_provider_type); |
| 258 if (!TranslateStringToONC( |
| 259 kVPNTypeTable, shill_provider_type, &onc_provider_type)) { |
| 260 return; |
| 261 } |
| 262 onc_object_->SetStringWithoutPathExpansion(::onc::vpn::kType, |
| 263 onc_provider_type); |
| 264 std::string provider_host; |
| 265 if (provider->GetStringWithoutPathExpansion(shill::kHostProperty, |
| 266 &provider_host)) { |
| 267 onc_object_->SetStringWithoutPathExpansion(::onc::vpn::kHost, |
| 268 provider_host); |
| 269 } |
| 270 |
| 271 // Translate the nested dictionary. |
| 272 std::string provider_type_dictionary; |
| 273 if (onc_provider_type == ::onc::vpn::kTypeL2TP_IPsec) { |
| 274 TranslateAndAddNestedObject(::onc::vpn::kIPsec, *provider); |
| 275 TranslateAndAddNestedObject(::onc::vpn::kL2TP, *provider); |
| 276 provider_type_dictionary = ::onc::vpn::kIPsec; |
| 277 } else { |
| 278 TranslateAndAddNestedObject(onc_provider_type, *provider); |
| 279 provider_type_dictionary = onc_provider_type; |
| 280 } |
| 281 |
| 282 bool save_credentials; |
| 283 if (shill_dictionary_->GetBooleanWithoutPathExpansion( |
| 284 shill::kSaveCredentialsProperty, &save_credentials)) { |
| 285 SetNestedOncValue(provider_type_dictionary, |
| 286 ::onc::vpn::kSaveCredentials, |
| 287 base::FundamentalValue(save_credentials)); |
| 249 } | 288 } |
| 250 } | 289 } |
| 251 | 290 |
| 252 void ShillToONCTranslator::TranslateWiFiWithState() { | 291 void ShillToONCTranslator::TranslateWiFiWithState() { |
| 253 TranslateWithTableAndSet( | 292 TranslateWithTableAndSet( |
| 254 shill::kSecurityProperty, kWiFiSecurityTable, ::onc::wifi::kSecurity); | 293 shill::kSecurityProperty, kWiFiSecurityTable, ::onc::wifi::kSecurity); |
| 255 std::string ssid = shill_property_util::GetSSIDFromProperties( | 294 std::string ssid = shill_property_util::GetSSIDFromProperties( |
| 256 *shill_dictionary_, NULL /* ignore unknown encoding */); | 295 *shill_dictionary_, NULL /* ignore unknown encoding */); |
| 257 if (!ssid.empty()) | 296 if (!ssid.empty()) |
| 258 onc_object_->SetStringWithoutPathExpansion(::onc::wifi::kSSID, ssid); | 297 onc_object_->SetStringWithoutPathExpansion(::onc::wifi::kSSID, ssid); |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 } | 443 } |
| 405 ShillToONCTranslator nested_translator(dictionary, | 444 ShillToONCTranslator nested_translator(dictionary, |
| 406 *field_signature->value_signature); | 445 *field_signature->value_signature); |
| 407 scoped_ptr<base::DictionaryValue> nested_object = | 446 scoped_ptr<base::DictionaryValue> nested_object = |
| 408 nested_translator.CreateTranslatedONCObject(); | 447 nested_translator.CreateTranslatedONCObject(); |
| 409 if (nested_object->empty()) | 448 if (nested_object->empty()) |
| 410 return; | 449 return; |
| 411 onc_object_->SetWithoutPathExpansion(onc_field_name, nested_object.release()); | 450 onc_object_->SetWithoutPathExpansion(onc_field_name, nested_object.release()); |
| 412 } | 451 } |
| 413 | 452 |
| 453 void ShillToONCTranslator::SetNestedOncValue( |
| 454 const std::string& onc_dictionary_name, |
| 455 const std::string& onc_field_name, |
| 456 const base::Value& value) { |
| 457 base::DictionaryValue* nested; |
| 458 if (!onc_object_->GetDictionaryWithoutPathExpansion( |
| 459 onc_dictionary_name, &nested)) { |
| 460 nested = new base::DictionaryValue; |
| 461 onc_object_->SetWithoutPathExpansion(onc_dictionary_name, nested); |
| 462 } |
| 463 nested->SetWithoutPathExpansion(onc_field_name, value.DeepCopy()); |
| 464 } |
| 465 |
| 414 void ShillToONCTranslator::TranslateAndAddListOfObjects( | 466 void ShillToONCTranslator::TranslateAndAddListOfObjects( |
| 415 const std::string& onc_field_name, | 467 const std::string& onc_field_name, |
| 416 const base::ListValue& list) { | 468 const base::ListValue& list) { |
| 417 const OncFieldSignature* field_signature = | 469 const OncFieldSignature* field_signature = |
| 418 GetFieldSignature(*onc_signature_, onc_field_name); | 470 GetFieldSignature(*onc_signature_, onc_field_name); |
| 419 if (field_signature->value_signature->onc_type != base::Value::TYPE_LIST) { | 471 if (field_signature->value_signature->onc_type != base::Value::TYPE_LIST) { |
| 420 LOG(ERROR) << "ONC Field name: '" << onc_field_name << "' has type '" | 472 LOG(ERROR) << "ONC Field name: '" << onc_field_name << "' has type '" |
| 421 << field_signature->value_signature->onc_type | 473 << field_signature->value_signature->onc_type |
| 422 << "', expected: base::Value::TYPE_LIST."; | 474 << "', expected: base::Value::TYPE_LIST: " << GetName(); |
| 423 return; | 475 return; |
| 424 } | 476 } |
| 425 DCHECK(field_signature->value_signature->onc_array_entry_signature); | 477 DCHECK(field_signature->value_signature->onc_array_entry_signature); |
| 426 scoped_ptr<base::ListValue> result(new base::ListValue()); | 478 scoped_ptr<base::ListValue> result(new base::ListValue()); |
| 427 for (base::ListValue::const_iterator it = list.begin(); | 479 for (base::ListValue::const_iterator it = list.begin(); |
| 428 it != list.end(); ++it) { | 480 it != list.end(); ++it) { |
| 429 const base::DictionaryValue* shill_value = NULL; | 481 const base::DictionaryValue* shill_value = NULL; |
| 430 if (!(*it)->GetAsDictionary(&shill_value)) | 482 if (!(*it)->GetAsDictionary(&shill_value)) |
| 431 continue; | 483 continue; |
| 432 ShillToONCTranslator nested_translator( | 484 ShillToONCTranslator nested_translator( |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 &shill_value)) { | 523 &shill_value)) { |
| 472 return; | 524 return; |
| 473 } | 525 } |
| 474 | 526 |
| 475 if (shill_value->GetType() != field_signature->value_signature->onc_type) { | 527 if (shill_value->GetType() != field_signature->value_signature->onc_type) { |
| 476 LOG(ERROR) << "Shill property '" << shill_property_name | 528 LOG(ERROR) << "Shill property '" << shill_property_name |
| 477 << "' with value " << *shill_value | 529 << "' with value " << *shill_value |
| 478 << " has base::Value::Type " << shill_value->GetType() | 530 << " has base::Value::Type " << shill_value->GetType() |
| 479 << " but ONC field '" << field_signature->onc_field_name | 531 << " but ONC field '" << field_signature->onc_field_name |
| 480 << "' requires type " | 532 << "' requires type " |
| 481 << field_signature->value_signature->onc_type << "."; | 533 << field_signature->value_signature->onc_type |
| 534 << ": " << GetName(); |
| 482 return; | 535 return; |
| 483 } | 536 } |
| 484 | 537 |
| 485 onc_object_->SetWithoutPathExpansion(field_signature->onc_field_name, | 538 onc_object_->SetWithoutPathExpansion(field_signature->onc_field_name, |
| 486 shill_value->DeepCopy()); | 539 shill_value->DeepCopy()); |
| 487 } | 540 } |
| 488 | 541 |
| 489 void ShillToONCTranslator::TranslateWithTableAndSet( | 542 void ShillToONCTranslator::TranslateWithTableAndSet( |
| 490 const std::string& shill_property_name, | 543 const std::string& shill_property_name, |
| 491 const StringTranslationEntry table[], | 544 const StringTranslationEntry table[], |
| 492 const std::string& onc_field_name) { | 545 const std::string& onc_field_name) { |
| 493 std::string shill_value; | 546 std::string shill_value; |
| 494 if (!shill_dictionary_->GetStringWithoutPathExpansion(shill_property_name, | 547 if (!shill_dictionary_->GetStringWithoutPathExpansion(shill_property_name, |
| 495 &shill_value)) { | 548 &shill_value)) { |
| 496 return; | 549 return; |
| 497 } | 550 } |
| 498 std::string onc_value; | 551 std::string onc_value; |
| 499 if (TranslateStringToONC(table, shill_value, &onc_value)) { | 552 if (TranslateStringToONC(table, shill_value, &onc_value)) { |
| 500 onc_object_->SetStringWithoutPathExpansion(onc_field_name, onc_value); | 553 onc_object_->SetStringWithoutPathExpansion(onc_field_name, onc_value); |
| 501 return; | 554 return; |
| 502 } | 555 } |
| 503 LOG(ERROR) << "Shill property '" << shill_property_name << "' with value " | 556 LOG(ERROR) << "Shill property '" << shill_property_name << "' with value " |
| 504 << shill_value << " couldn't be translated to ONC"; | 557 << shill_value << " couldn't be translated to ONC: " << GetName(); |
| 558 } |
| 559 |
| 560 std::string ShillToONCTranslator::GetName() { |
| 561 DCHECK(shill_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 |