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(kClientCertType, &clientcert_type); 108 RemoveEntryUnless( 109 eap, kClientCertPattern, clientcert_type == ::onc::certificate::kPattern); 110 RemoveEntryUnless( 111 eap, kClientCertRef, clientcert_type == ::onc::certificate::kRef); 112 113 std::string outer; 114 eap->GetStringWithoutPathExpansion(kOuter, &outer); 115 RemoveEntryUnless(eap, kAnonymousIdentity, 116 outer == kPEAP || outer == kEAP_TTLS); 117 RemoveEntryUnless(eap, kInner, 118 outer == kPEAP || outer == kEAP_TTLS || outer == kEAP_FAST); 119 } 120 121 void Normalizer::NormalizeIPsec(base::DictionaryValue* ipsec) { 122 using namespace ::onc::ipsec; 123 124 std::string auth_type; 125 ipsec->GetStringWithoutPathExpansion(kAuthenticationType, &auth_type); 126 RemoveEntryUnless(ipsec, ::onc::vpn::kClientCertType, auth_type == kCert); 127 RemoveEntryUnless(ipsec, kServerCARef, auth_type == kCert); 128 RemoveEntryUnless(ipsec, kPSK, auth_type == kPSK); 129 RemoveEntryUnless(ipsec, ::onc::vpn::kSaveCredentials, auth_type == kPSK); 130 131 std::string clientcert_type; 132 ipsec->GetStringWithoutPathExpansion(::onc::vpn::kClientCertType, 133 &clientcert_type); 134 RemoveEntryUnless(ipsec, 135 ::onc::vpn::kClientCertPattern, 136 clientcert_type == ::onc::certificate::kPattern); 137 RemoveEntryUnless(ipsec, 138 ::onc::vpn::kClientCertRef, 139 clientcert_type == ::onc::certificate::kRef); 140 141 int ike_version = -1; 142 ipsec->GetIntegerWithoutPathExpansion(kIKEVersion, &ike_version); 143 RemoveEntryUnless(ipsec, kEAP, ike_version == 2); 144 RemoveEntryUnless(ipsec, kGroup, ike_version == 1); 145 RemoveEntryUnless(ipsec, kXAUTH, ike_version == 1); 146 } 147 148 void Normalizer::NormalizeNetworkConfiguration(base::DictionaryValue* network) { 149 bool remove = false; 150 network->GetBooleanWithoutPathExpansion(::onc::kRemove, &remove); 151 if (remove) { 152 network->RemoveWithoutPathExpansion(::onc::network_config::kIPConfigs, 153 NULL); 154 network->RemoveWithoutPathExpansion(::onc::network_config::kName, NULL); 155 network->RemoveWithoutPathExpansion(::onc::network_config::kNameServers, 156 NULL); 157 network->RemoveWithoutPathExpansion(::onc::network_config::kProxySettings, 158 NULL); 159 network->RemoveWithoutPathExpansion(::onc::network_config::kSearchDomains, 160 NULL); 161 network->RemoveWithoutPathExpansion(::onc::network_config::kType, NULL); 162 // Fields dependent on kType are removed afterwards, too. 163 } 164 165 std::string type; 166 network->GetStringWithoutPathExpansion(::onc::network_config::kType, &type); 167 RemoveEntryUnless(network, 168 ::onc::network_config::kEthernet, 169 type == ::onc::network_type::kEthernet); 170 RemoveEntryUnless( 171 network, ::onc::network_config::kVPN, type == ::onc::network_type::kVPN); 172 RemoveEntryUnless(network, 173 ::onc::network_config::kWiFi, 174 type == ::onc::network_type::kWiFi); 175 } 176 177 void Normalizer::NormalizeOpenVPN(base::DictionaryValue* openvpn) { 178 using namespace ::onc::vpn; 179 180 std::string clientcert_type; 181 openvpn->GetStringWithoutPathExpansion(kClientCertType, &clientcert_type); 182 RemoveEntryUnless(openvpn, 183 kClientCertPattern, 184 clientcert_type == ::onc::certificate::kPattern); 185 RemoveEntryUnless( 186 openvpn, kClientCertRef, clientcert_type == ::onc::certificate::kRef); 187 } 188 189 void Normalizer::NormalizeProxySettings(base::DictionaryValue* proxy) { 190 using namespace ::onc::proxy; 191 192 std::string type; 193 proxy->GetStringWithoutPathExpansion(::onc::proxy::kType, &type); 194 RemoveEntryUnless(proxy, kManual, type == kManual); 195 RemoveEntryUnless(proxy, kExcludeDomains, type == kManual); 196 RemoveEntryUnless(proxy, kPAC, type == kPAC); 197 } 198 199 void Normalizer::NormalizeVPN(base::DictionaryValue* vpn) { 200 using namespace ::onc::vpn; 201 202 std::string type; 203 vpn->GetStringWithoutPathExpansion(::onc::vpn::kType, &type); 204 RemoveEntryUnless(vpn, kOpenVPN, type == kOpenVPN); 205 RemoveEntryUnless(vpn, kIPsec, type == kIPsec || type == kTypeL2TP_IPsec); 206 RemoveEntryUnless(vpn, kL2TP, type == kTypeL2TP_IPsec); 207 } 208 209 void Normalizer::NormalizeWiFi(base::DictionaryValue* wifi) { 210 using namespace ::onc::wifi; 211 212 std::string security; 213 wifi->GetStringWithoutPathExpansion(::onc::wifi::kSecurity, &security); 214 RemoveEntryUnless(wifi, kEAP, security == kWEP_8021X || security == kWPA_EAP); 215 RemoveEntryUnless(wifi, kPassphrase, 216 security == kWEP_PSK || security == kWPA_PSK); 217 } 218 219 } // namespace onc 220 } // namespace chromeos 221