onc_normalizer.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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.
4
5#include "chromeos/network/onc/onc_normalizer.h"
6
7#include <string>
8
9#include "base/logging.h"
10#include "base/values.h"
11#include "chromeos/network/onc/onc_signature.h"
12#include "components/onc/onc_constants.h"
13
14namespace chromeos {
15namespace onc {
16
17Normalizer::Normalizer(bool remove_recommended_fields)
18    : remove_recommended_fields_(remove_recommended_fields) {
19}
20
21Normalizer::~Normalizer() {
22}
23
24scoped_ptr<base::DictionaryValue> Normalizer::NormalizeObject(
25    const OncValueSignature* object_signature,
26    const base::DictionaryValue& onc_object) {
27  CHECK(object_signature != NULL);
28  bool error = false;
29  scoped_ptr<base::DictionaryValue> result =
30      MapObject(*object_signature, onc_object, &error);
31  DCHECK(!error);
32  return result.Pass();
33}
34
35scoped_ptr<base::DictionaryValue> Normalizer::MapObject(
36    const OncValueSignature& signature,
37    const base::DictionaryValue& onc_object,
38    bool* error) {
39  scoped_ptr<base::DictionaryValue> normalized =
40      Mapper::MapObject(signature, onc_object, error);
41
42  if (normalized.get() == NULL)
43    return scoped_ptr<base::DictionaryValue>();
44
45  if (remove_recommended_fields_)
46    normalized->RemoveWithoutPathExpansion(::onc::kRecommended, NULL);
47
48  if (&signature == &kCertificateSignature)
49    NormalizeCertificate(normalized.get());
50  else if (&signature == &kEAPSignature)
51    NormalizeEAP(normalized.get());
52  else if (&signature == &kEthernetSignature)
53    NormalizeEthernet(normalized.get());
54  else if (&signature == &kIPsecSignature)
55    NormalizeIPsec(normalized.get());
56  else if (&signature == &kNetworkConfigurationSignature)
57    NormalizeNetworkConfiguration(normalized.get());
58  else if (&signature == &kOpenVPNSignature)
59    NormalizeOpenVPN(normalized.get());
60  else if (&signature == &kProxySettingsSignature)
61    NormalizeProxySettings(normalized.get());
62  else if (&signature == &kVPNSignature)
63    NormalizeVPN(normalized.get());
64  else if (&signature == &kWiFiSignature)
65    NormalizeWiFi(normalized.get());
66
67  return normalized.Pass();
68}
69
70namespace {
71
72void RemoveEntryUnless(base::DictionaryValue* dict,
73                       const std::string& path,
74                       bool condition) {
75  if (!condition)
76    dict->RemoveWithoutPathExpansion(path, NULL);
77}
78
79}  // namespace
80
81void Normalizer::NormalizeCertificate(base::DictionaryValue* cert) {
82  using namespace ::onc::certificate;
83
84  bool remove = false;
85  cert->GetBooleanWithoutPathExpansion(::onc::kRemove, &remove);
86  RemoveEntryUnless(cert, ::onc::certificate::kType, !remove);
87
88  std::string type;
89  cert->GetStringWithoutPathExpansion(::onc::certificate::kType, &type);
90  RemoveEntryUnless(cert, kPKCS12, type == kClient);
91  RemoveEntryUnless(cert, kTrustBits, type == kServer || type == kAuthority);
92  RemoveEntryUnless(cert, kX509, type == kServer || type == kAuthority);
93}
94
95void Normalizer::NormalizeEthernet(base::DictionaryValue* ethernet) {
96  using namespace ::onc::ethernet;
97
98  std::string auth;
99  ethernet->GetStringWithoutPathExpansion(kAuthentication, &auth);
100  RemoveEntryUnless(ethernet, kEAP, auth == k8021X);
101}
102
103void Normalizer::NormalizeEAP(base::DictionaryValue* eap) {
104  using namespace ::onc::eap;
105
106  std::string clientcert_type;
107  eap->GetStringWithoutPathExpansion(::onc::client_cert::kClientCertType,
108                                     &clientcert_type);
109  RemoveEntryUnless(eap,
110                    ::onc::client_cert::kClientCertPattern,
111                    clientcert_type == ::onc::client_cert::kPattern);
112  RemoveEntryUnless(eap,
113                    ::onc::client_cert::kClientCertRef,
114                    clientcert_type == ::onc::client_cert::kRef);
115
116  std::string outer;
117  eap->GetStringWithoutPathExpansion(kOuter, &outer);
118  RemoveEntryUnless(eap, kAnonymousIdentity,
119                    outer == kPEAP || outer == kEAP_TTLS);
120  RemoveEntryUnless(eap, kInner,
121                    outer == kPEAP || outer == kEAP_TTLS || outer == kEAP_FAST);
122}
123
124void Normalizer::NormalizeIPsec(base::DictionaryValue* ipsec) {
125  using namespace ::onc::ipsec;
126
127  std::string auth_type;
128  ipsec->GetStringWithoutPathExpansion(kAuthenticationType, &auth_type);
129  RemoveEntryUnless(
130      ipsec, ::onc::client_cert::kClientCertType, auth_type == kCert);
131  RemoveEntryUnless(ipsec, kServerCARef, auth_type == kCert);
132  RemoveEntryUnless(ipsec, kPSK, auth_type == kPSK);
133  RemoveEntryUnless(ipsec, ::onc::vpn::kSaveCredentials, auth_type == kPSK);
134
135  std::string clientcert_type;
136  ipsec->GetStringWithoutPathExpansion(::onc::client_cert::kClientCertType,
137                                       &clientcert_type);
138  RemoveEntryUnless(ipsec,
139                    ::onc::client_cert::kClientCertPattern,
140                    clientcert_type == ::onc::client_cert::kPattern);
141  RemoveEntryUnless(ipsec,
142                    ::onc::client_cert::kClientCertRef,
143                    clientcert_type == ::onc::client_cert::kRef);
144
145  int ike_version = -1;
146  ipsec->GetIntegerWithoutPathExpansion(kIKEVersion, &ike_version);
147  RemoveEntryUnless(ipsec, kEAP, ike_version == 2);
148  RemoveEntryUnless(ipsec, kGroup, ike_version == 1);
149  RemoveEntryUnless(ipsec, kXAUTH, ike_version == 1);
150}
151
152void Normalizer::NormalizeNetworkConfiguration(base::DictionaryValue* network) {
153  bool remove = false;
154  network->GetBooleanWithoutPathExpansion(::onc::kRemove, &remove);
155  if (remove) {
156    network->RemoveWithoutPathExpansion(::onc::network_config::kStaticIPConfig,
157                                        NULL);
158    network->RemoveWithoutPathExpansion(::onc::network_config::kName, NULL);
159    network->RemoveWithoutPathExpansion(::onc::network_config::kNameServers,
160                                        NULL);
161    network->RemoveWithoutPathExpansion(::onc::network_config::kProxySettings,
162                                        NULL);
163    network->RemoveWithoutPathExpansion(::onc::network_config::kSearchDomains,
164                                        NULL);
165    network->RemoveWithoutPathExpansion(::onc::network_config::kType, NULL);
166    // Fields dependent on kType are removed afterwards, too.
167  }
168
169  std::string type;
170  network->GetStringWithoutPathExpansion(::onc::network_config::kType, &type);
171  RemoveEntryUnless(network,
172                    ::onc::network_config::kEthernet,
173                    type == ::onc::network_type::kEthernet);
174  RemoveEntryUnless(
175      network, ::onc::network_config::kVPN, type == ::onc::network_type::kVPN);
176  RemoveEntryUnless(network,
177                    ::onc::network_config::kWiFi,
178                    type == ::onc::network_type::kWiFi);
179}
180
181void Normalizer::NormalizeOpenVPN(base::DictionaryValue* openvpn) {
182  using namespace ::onc::vpn;
183
184  std::string clientcert_type;
185  openvpn->GetStringWithoutPathExpansion(::onc::client_cert::kClientCertType,
186                                         &clientcert_type);
187  RemoveEntryUnless(openvpn,
188                    ::onc::client_cert::kClientCertPattern,
189                    clientcert_type == ::onc::client_cert::kPattern);
190  RemoveEntryUnless(openvpn,
191                    ::onc::client_cert::kClientCertRef,
192                    clientcert_type == ::onc::client_cert::kRef);
193}
194
195void Normalizer::NormalizeProxySettings(base::DictionaryValue* proxy) {
196  using namespace ::onc::proxy;
197
198  std::string type;
199  proxy->GetStringWithoutPathExpansion(::onc::proxy::kType, &type);
200  RemoveEntryUnless(proxy, kManual, type == kManual);
201  RemoveEntryUnless(proxy, kExcludeDomains, type == kManual);
202  RemoveEntryUnless(proxy, kPAC, type == kPAC);
203}
204
205void Normalizer::NormalizeVPN(base::DictionaryValue* vpn) {
206  using namespace ::onc::vpn;
207
208  std::string type;
209  vpn->GetStringWithoutPathExpansion(::onc::vpn::kType, &type);
210  RemoveEntryUnless(vpn, kOpenVPN, type == kOpenVPN);
211  RemoveEntryUnless(vpn, kIPsec, type == kIPsec || type == kTypeL2TP_IPsec);
212  RemoveEntryUnless(vpn, kL2TP, type == kTypeL2TP_IPsec);
213}
214
215void Normalizer::NormalizeWiFi(base::DictionaryValue* wifi) {
216  using namespace ::onc::wifi;
217
218  std::string security;
219  wifi->GetStringWithoutPathExpansion(::onc::wifi::kSecurity, &security);
220  RemoveEntryUnless(wifi, kEAP, security == kWEP_8021X || security == kWPA_EAP);
221  RemoveEntryUnless(wifi, kPassphrase,
222                    security == kWEP_PSK || security == kWPA_PSK);
223}
224
225}  // namespace onc
226}  // namespace chromeos
227