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 |