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
3 // found in the LICENSE file.
5 #include "chromeos/network/network_ui_data.h"
7 #include "base/logging.h"
8 #include "base/values.h"
9 #include "chromeos/network/onc/onc_signature.h"
13 // Top-level UI data dictionary keys.
14 const char NetworkUIData::kKeyONCSource
[] = "onc_source";
15 const char NetworkUIData::kKeyCertificatePattern
[] = "certificate_pattern";
16 const char NetworkUIData::kKeyCertificateType
[] = "certificate_type";
17 const char NetworkUIData::kKeyUserSettings
[] = "user_settings";
21 template <typename Enum
>
22 struct StringEnumEntry
{
27 const StringEnumEntry
< ::onc::ONCSource
> kONCSourceTable
[] = {
28 { "user_import", ::onc::ONC_SOURCE_USER_IMPORT
},
29 { "device_policy", ::onc::ONC_SOURCE_DEVICE_POLICY
},
30 { "user_policy", ::onc::ONC_SOURCE_USER_POLICY
}
33 const StringEnumEntry
<ClientCertType
> kClientCertTable
[] = {
34 { "none", CLIENT_CERT_TYPE_NONE
},
35 { "pattern", CLIENT_CERT_TYPE_PATTERN
},
36 { "ref", CLIENT_CERT_TYPE_REF
}
39 // Converts |enum_value| to the corresponding string according to |table|. If no
40 // enum value of the table matches (which can only occur if incorrect casting
41 // was used to obtain |enum_value|), returns an empty string instead.
42 template <typename Enum
, int N
>
43 std::string
EnumToString(const StringEnumEntry
<Enum
>(& table
)[N
],
45 for (int i
= 0; i
< N
; ++i
) {
46 if (table
[i
].enum_value
== enum_value
)
47 return table
[i
].string
;
52 // Converts |str| to the corresponding enum value according to |table|. If no
53 // string of the table matches, returns |fallback| instead.
54 template<typename Enum
, int N
>
55 Enum
StringToEnum(const StringEnumEntry
<Enum
>(& table
)[N
],
56 const std::string
& str
,
58 for (int i
= 0; i
< N
; ++i
) {
59 if (table
[i
].string
== str
)
60 return table
[i
].enum_value
;
67 NetworkUIData::NetworkUIData()
68 : onc_source_(::onc::ONC_SOURCE_NONE
),
69 certificate_type_(CLIENT_CERT_TYPE_NONE
) {
72 NetworkUIData::NetworkUIData(const NetworkUIData
& other
) {
76 NetworkUIData
& NetworkUIData::operator=(const NetworkUIData
& other
) {
77 certificate_pattern_
= other
.certificate_pattern_
;
78 onc_source_
= other
.onc_source_
;
79 certificate_type_
= other
.certificate_type_
;
80 if (other
.user_settings_
)
81 user_settings_
.reset(other
.user_settings_
->DeepCopy());
82 policy_guid_
= other
.policy_guid_
;
86 NetworkUIData::NetworkUIData(const base::DictionaryValue
& dict
) {
88 dict
.GetString(kKeyONCSource
, &source
);
89 onc_source_
= StringToEnum(kONCSourceTable
, source
, ::onc::ONC_SOURCE_NONE
);
91 std::string type_string
;
92 dict
.GetString(kKeyCertificateType
, &type_string
);
94 StringToEnum(kClientCertTable
, type_string
, CLIENT_CERT_TYPE_NONE
);
96 if (certificate_type_
== CLIENT_CERT_TYPE_PATTERN
) {
97 const base::DictionaryValue
* cert_dict
= NULL
;
98 dict
.GetDictionary(kKeyCertificatePattern
, &cert_dict
);
100 certificate_pattern_
.CopyFromDictionary(*cert_dict
);
101 if (certificate_pattern_
.Empty()) {
102 // This case may occur if UIData from an older CrOS version is read.
103 LOG(WARNING
) << "Couldn't parse a valid certificate pattern.";
104 certificate_type_
= CLIENT_CERT_TYPE_NONE
;
108 const base::DictionaryValue
* user_settings
= NULL
;
109 if (dict
.GetDictionary(kKeyUserSettings
, &user_settings
))
110 user_settings_
.reset(user_settings
->DeepCopy());
113 NetworkUIData::~NetworkUIData() {
116 void NetworkUIData::set_user_settings(scoped_ptr
<base::DictionaryValue
> dict
) {
117 user_settings_
= dict
.Pass();
120 void NetworkUIData::FillDictionary(base::DictionaryValue
* dict
) const {
123 std::string source_string
= EnumToString(kONCSourceTable
, onc_source_
);
124 if (!source_string
.empty())
125 dict
->SetString(kKeyONCSource
, source_string
);
127 if (certificate_type_
!= CLIENT_CERT_TYPE_NONE
) {
128 std::string type_string
= EnumToString(kClientCertTable
, certificate_type_
);
129 dict
->SetString(kKeyCertificateType
, type_string
);
131 if (certificate_type_
== CLIENT_CERT_TYPE_PATTERN
&&
132 !certificate_pattern_
.Empty()) {
133 dict
->Set(kKeyCertificatePattern
,
134 certificate_pattern_
.CreateAsDictionary());
138 dict
->SetWithoutPathExpansion(kKeyUserSettings
,
139 user_settings_
->DeepCopy());
144 void TranslateClientCertType(const std::string
& client_cert_type
,
145 NetworkUIData
* ui_data
) {
146 using namespace ::onc::certificate
;
148 if (client_cert_type
== kNone
) {
149 type
= CLIENT_CERT_TYPE_NONE
;
150 } else if (client_cert_type
== kRef
) {
151 type
= CLIENT_CERT_TYPE_REF
;
152 } else if (client_cert_type
== kPattern
) {
153 type
= CLIENT_CERT_TYPE_PATTERN
;
155 type
= CLIENT_CERT_TYPE_NONE
;
159 ui_data
->set_certificate_type(type
);
162 void TranslateCertificatePattern(const base::DictionaryValue
& onc_object
,
163 NetworkUIData
* ui_data
) {
164 CertificatePattern pattern
;
165 bool success
= pattern
.CopyFromDictionary(onc_object
);
167 ui_data
->set_certificate_pattern(pattern
);
170 void TranslateEAP(const base::DictionaryValue
& eap
,
171 NetworkUIData
* ui_data
) {
172 std::string client_cert_type
;
173 if (eap
.GetStringWithoutPathExpansion(::onc::eap::kClientCertType
,
174 &client_cert_type
)) {
175 TranslateClientCertType(client_cert_type
, ui_data
);
179 void TranslateIPsec(const base::DictionaryValue
& ipsec
,
180 NetworkUIData
* ui_data
) {
181 std::string client_cert_type
;
182 if (ipsec
.GetStringWithoutPathExpansion(::onc::vpn::kClientCertType
,
183 &client_cert_type
)) {
184 TranslateClientCertType(client_cert_type
, ui_data
);
188 void TranslateOpenVPN(const base::DictionaryValue
& openvpn
,
189 NetworkUIData
* ui_data
) {
190 std::string client_cert_type
;
191 if (openvpn
.GetStringWithoutPathExpansion(::onc::vpn::kClientCertType
,
192 &client_cert_type
)) {
193 TranslateClientCertType(client_cert_type
, ui_data
);
197 void TranslateONCHierarchy(const onc::OncValueSignature
& signature
,
198 const base::DictionaryValue
& onc_object
,
199 NetworkUIData
* ui_data
) {
200 if (&signature
== &onc::kCertificatePatternSignature
)
201 TranslateCertificatePattern(onc_object
, ui_data
);
202 else if (&signature
== &onc::kEAPSignature
)
203 TranslateEAP(onc_object
, ui_data
);
204 else if (&signature
== &onc::kIPsecSignature
)
205 TranslateIPsec(onc_object
, ui_data
);
206 else if (&signature
== &onc::kOpenVPNSignature
)
207 TranslateOpenVPN(onc_object
, ui_data
);
209 // Recurse into nested objects.
210 for (base::DictionaryValue::Iterator
it(onc_object
); !it
.IsAtEnd();
212 const base::DictionaryValue
* inner_object
;
213 if (!it
.value().GetAsDictionary(&inner_object
))
216 const onc::OncFieldSignature
* field_signature
=
217 GetFieldSignature(signature
, it
.key());
219 TranslateONCHierarchy(*field_signature
->value_signature
, *inner_object
,
227 scoped_ptr
<NetworkUIData
> NetworkUIData::CreateFromONC(
228 ::onc::ONCSource onc_source
,
229 const base::DictionaryValue
& onc_network
) {
230 scoped_ptr
<NetworkUIData
> ui_data(new NetworkUIData());
231 TranslateONCHierarchy(onc::kNetworkConfigurationSignature
, onc_network
,
234 ui_data
->set_onc_source(onc_source
);
236 return ui_data
.Pass();
239 } // namespace chromeos