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";
18 const char NetworkUIData::kONCSourceUserImport
[] = "user_import";
19 const char NetworkUIData::kONCSourceDevicePolicy
[] = "device_policy";
20 const char NetworkUIData::kONCSourceUserPolicy
[] = "user_policy";
24 template <typename Enum
>
25 struct StringEnumEntry
{
30 const StringEnumEntry
< ::onc::ONCSource
> kONCSourceTable
[] = {
31 { NetworkUIData::kONCSourceUserImport
, ::onc::ONC_SOURCE_USER_IMPORT
},
32 { NetworkUIData::kONCSourceDevicePolicy
, ::onc::ONC_SOURCE_DEVICE_POLICY
},
33 { NetworkUIData::kONCSourceUserPolicy
, ::onc::ONC_SOURCE_USER_POLICY
}
36 const StringEnumEntry
<ClientCertType
> kClientCertTable
[] = {
37 { "none", CLIENT_CERT_TYPE_NONE
},
38 { "pattern", CLIENT_CERT_TYPE_PATTERN
},
39 { "ref", CLIENT_CERT_TYPE_REF
}
42 // Converts |enum_value| to the corresponding string according to |table|. If no
43 // enum value of the table matches (which can only occur if incorrect casting
44 // was used to obtain |enum_value|), returns an empty string instead.
45 template <typename Enum
, int N
>
46 std::string
EnumToString(const StringEnumEntry
<Enum
>(& table
)[N
],
48 for (int i
= 0; i
< N
; ++i
) {
49 if (table
[i
].enum_value
== enum_value
)
50 return table
[i
].string
;
55 // Converts |str| to the corresponding enum value according to |table|. If no
56 // string of the table matches, returns |fallback| instead.
57 template<typename Enum
, int N
>
58 Enum
StringToEnum(const StringEnumEntry
<Enum
>(& table
)[N
],
59 const std::string
& str
,
61 for (int i
= 0; i
< N
; ++i
) {
62 if (table
[i
].string
== str
)
63 return table
[i
].enum_value
;
70 NetworkUIData::NetworkUIData()
71 : onc_source_(::onc::ONC_SOURCE_NONE
),
72 certificate_type_(CLIENT_CERT_TYPE_NONE
) {
75 NetworkUIData::NetworkUIData(const NetworkUIData
& other
) {
79 NetworkUIData
& NetworkUIData::operator=(const NetworkUIData
& other
) {
80 certificate_pattern_
= other
.certificate_pattern_
;
81 onc_source_
= other
.onc_source_
;
82 certificate_type_
= other
.certificate_type_
;
83 if (other
.user_settings_
)
84 user_settings_
.reset(other
.user_settings_
->DeepCopy());
85 policy_guid_
= other
.policy_guid_
;
89 NetworkUIData::NetworkUIData(const base::DictionaryValue
& dict
) {
91 dict
.GetString(kKeyONCSource
, &source
);
92 onc_source_
= StringToEnum(kONCSourceTable
, source
, ::onc::ONC_SOURCE_NONE
);
94 std::string type_string
;
95 dict
.GetString(kKeyCertificateType
, &type_string
);
97 StringToEnum(kClientCertTable
, type_string
, CLIENT_CERT_TYPE_NONE
);
99 if (certificate_type_
== CLIENT_CERT_TYPE_PATTERN
) {
100 const base::DictionaryValue
* cert_dict
= NULL
;
101 dict
.GetDictionary(kKeyCertificatePattern
, &cert_dict
);
103 certificate_pattern_
.CopyFromDictionary(*cert_dict
);
104 if (certificate_pattern_
.Empty()) {
105 // This case may occur if UIData from an older CrOS version is read.
106 LOG(WARNING
) << "Couldn't parse a valid certificate pattern.";
107 certificate_type_
= CLIENT_CERT_TYPE_NONE
;
111 const base::DictionaryValue
* user_settings
= NULL
;
112 if (dict
.GetDictionary(kKeyUserSettings
, &user_settings
))
113 user_settings_
.reset(user_settings
->DeepCopy());
116 NetworkUIData::~NetworkUIData() {
119 void NetworkUIData::set_user_settings(scoped_ptr
<base::DictionaryValue
> dict
) {
120 user_settings_
= dict
.Pass();
123 std::string
NetworkUIData::GetONCSourceAsString() const {
124 return EnumToString(kONCSourceTable
, onc_source_
);
127 void NetworkUIData::FillDictionary(base::DictionaryValue
* dict
) const {
130 std::string source_string
= GetONCSourceAsString();
131 if (!source_string
.empty())
132 dict
->SetString(kKeyONCSource
, source_string
);
134 if (certificate_type_
!= CLIENT_CERT_TYPE_NONE
) {
135 std::string type_string
= EnumToString(kClientCertTable
, certificate_type_
);
136 dict
->SetString(kKeyCertificateType
, type_string
);
138 if (certificate_type_
== CLIENT_CERT_TYPE_PATTERN
&&
139 !certificate_pattern_
.Empty()) {
140 dict
->Set(kKeyCertificatePattern
,
141 certificate_pattern_
.CreateAsDictionary());
145 dict
->SetWithoutPathExpansion(kKeyUserSettings
,
146 user_settings_
->DeepCopy());
151 void TranslateClientCertType(const std::string
& client_cert_type
,
152 NetworkUIData
* ui_data
) {
153 using namespace ::onc::certificate
;
155 if (client_cert_type
== kNone
) {
156 type
= CLIENT_CERT_TYPE_NONE
;
157 } else if (client_cert_type
== kRef
) {
158 type
= CLIENT_CERT_TYPE_REF
;
159 } else if (client_cert_type
== kPattern
) {
160 type
= CLIENT_CERT_TYPE_PATTERN
;
162 type
= CLIENT_CERT_TYPE_NONE
;
166 ui_data
->set_certificate_type(type
);
169 void TranslateCertificatePattern(const base::DictionaryValue
& onc_object
,
170 NetworkUIData
* ui_data
) {
171 CertificatePattern pattern
;
172 bool success
= pattern
.CopyFromDictionary(onc_object
);
174 ui_data
->set_certificate_pattern(pattern
);
177 void TranslateEAP(const base::DictionaryValue
& eap
,
178 NetworkUIData
* ui_data
) {
179 std::string client_cert_type
;
180 if (eap
.GetStringWithoutPathExpansion(::onc::eap::kClientCertType
,
181 &client_cert_type
)) {
182 TranslateClientCertType(client_cert_type
, ui_data
);
186 void TranslateIPsec(const base::DictionaryValue
& ipsec
,
187 NetworkUIData
* ui_data
) {
188 std::string client_cert_type
;
189 if (ipsec
.GetStringWithoutPathExpansion(::onc::vpn::kClientCertType
,
190 &client_cert_type
)) {
191 TranslateClientCertType(client_cert_type
, ui_data
);
195 void TranslateOpenVPN(const base::DictionaryValue
& openvpn
,
196 NetworkUIData
* ui_data
) {
197 std::string client_cert_type
;
198 if (openvpn
.GetStringWithoutPathExpansion(::onc::vpn::kClientCertType
,
199 &client_cert_type
)) {
200 TranslateClientCertType(client_cert_type
, ui_data
);
204 void TranslateONCHierarchy(const onc::OncValueSignature
& signature
,
205 const base::DictionaryValue
& onc_object
,
206 NetworkUIData
* ui_data
) {
207 if (&signature
== &onc::kCertificatePatternSignature
)
208 TranslateCertificatePattern(onc_object
, ui_data
);
209 else if (&signature
== &onc::kEAPSignature
)
210 TranslateEAP(onc_object
, ui_data
);
211 else if (&signature
== &onc::kIPsecSignature
)
212 TranslateIPsec(onc_object
, ui_data
);
213 else if (&signature
== &onc::kOpenVPNSignature
)
214 TranslateOpenVPN(onc_object
, ui_data
);
216 // Recurse into nested objects.
217 for (base::DictionaryValue::Iterator
it(onc_object
); !it
.IsAtEnd();
219 const base::DictionaryValue
* inner_object
;
220 if (!it
.value().GetAsDictionary(&inner_object
))
223 const onc::OncFieldSignature
* field_signature
=
224 GetFieldSignature(signature
, it
.key());
226 TranslateONCHierarchy(*field_signature
->value_signature
, *inner_object
,
234 scoped_ptr
<NetworkUIData
> NetworkUIData::CreateFromONC(
235 ::onc::ONCSource onc_source
,
236 const base::DictionaryValue
& onc_network
) {
237 scoped_ptr
<NetworkUIData
> ui_data(new NetworkUIData());
238 TranslateONCHierarchy(onc::kNetworkConfigurationSignature
, onc_network
,
241 ui_data
->set_onc_source(onc_source
);
243 return ui_data
.Pass();
246 } // namespace chromeos