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 14 namespace chromeos { 15 namespace onc { 16 17 Normalizer::Normalizer(bool remove_recommended_fields) 18 : remove_recommended_fields_(remove_recommended_fields) { 19 } 20 21 Normalizer::~Normalizer() { 22 } 23 24 scoped_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 35 scoped_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 70 namespace { 71 72 void 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 81 void 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 95 void 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 103 void 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 124 void 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 152 void 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 181 void 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 195 void 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 205 void 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 215 void 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