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 #ifndef CHROMEOS_NETWORK_ONC_ONC_VALIDATOR_H_ 6 #define CHROMEOS_NETWORK_ONC_ONC_VALIDATOR_H_ 7 8 #include <set> 9 #include <string> 10 #include <vector> 11 12 #include "base/memory/scoped_ptr.h" 13 #include "chromeos/chromeos_export.h" 14 #include "chromeos/network/onc/onc_mapper.h" 15 #include "components/onc/onc_constants.h" 16 17 namespace base { 18 class DictionaryValue; 19 class Value; 20 } 21 22 namespace chromeos { 23 namespace onc { 24 25 struct OncValueSignature; 26 27 // The ONC Validator searches for the following invalid cases: 28 // - a value is found that has the wrong type or is not expected according to 29 // the ONC spec (always an error) 30 // 31 // - a field name is found that is not part of the signature 32 // (controlled by flag |error_on_unknown_field|) 33 // 34 // - a kRecommended array contains a field name that is not part of the 35 // enclosing object's signature or if that field is dictionary typed 36 // (controlled by flag |error_on_wrong_recommended|) 37 // 38 // - |managed_onc| is false and a field with name kRecommended is found 39 // (always ignored) 40 // 41 // - a required field is missing (controlled by flag |error_on_missing_field|) 42 // 43 // If one of these invalid cases occurs and, in case of a controlling flag, that 44 // flag is true, then it is an error. The function ValidateAndRepairObject sets 45 // |result| to INVALID and returns NULL. 46 // 47 // Otherwise, a DeepCopy of the validated object is created, which contains 48 // all but the invalid fields and values. 49 // 50 // If one of the invalid cases occurs and the controlling flag is false, then 51 // it is a warning. The function ValidateAndRepairObject sets |result| to 52 // VALID_WITH_WARNINGS and returns the repaired copy. 53 // 54 // If no error occurred, |result| is set to VALID and an exact DeepCopy is 55 // returned. 56 class CHROMEOS_EXPORT Validator : public Mapper { 57 public: 58 enum Result { 59 VALID, 60 VALID_WITH_WARNINGS, 61 INVALID 62 }; 63 64 // See the class comment. 65 Validator(bool error_on_unknown_field, 66 bool error_on_wrong_recommended, 67 bool error_on_missing_field, 68 bool managed_onc); 69 70 virtual ~Validator(); 71 72 // Sets the ONC source to |source|. If not set, defaults to ONC_SOURCE_NONE. 73 // If the source is set to ONC_SOURCE_DEVICE_POLICY, validation additionally 74 // checks: 75 // - only the network types Wifi and Ethernet are allowed 76 // - client certificate patterns are disallowed SetOncSource(::onc::ONCSource source)77 void SetOncSource(::onc::ONCSource source) { 78 onc_source_ = source; 79 } 80 81 // Validate the given |onc_object| according to |object_signature|. The 82 // |object_signature| has to be a pointer to one of the signatures in 83 // |onc_signature.h|. If an error is found, the function returns NULL and sets 84 // |result| to INVALID. If possible (no error encountered) a DeepCopy is 85 // created that contains all but the invalid fields and values and returns 86 // this "repaired" object. That means, if not handled as an error, then the 87 // following are dropped from the copy: 88 // - unknown fields 89 // - invalid field names in kRecommended arrays 90 // - kRecommended fields in an unmanaged ONC 91 // If any of these cases occurred, sets |result| to VALID_WITH_WARNINGS and 92 // otherwise to VALID. 93 // For details, see the class comment. 94 scoped_ptr<base::DictionaryValue> ValidateAndRepairObject( 95 const OncValueSignature* object_signature, 96 const base::DictionaryValue& onc_object, 97 Result* result); 98 99 private: 100 // Overridden from Mapper: 101 // Compare |onc_value|s type with |onc_type| and validate/repair according to 102 // |signature|. On error returns NULL. 103 virtual scoped_ptr<base::Value> MapValue(const OncValueSignature& signature, 104 const base::Value& onc_value, 105 bool* error) OVERRIDE; 106 107 // Dispatch to the right validation function according to 108 // |signature|. Iterates over all fields and recursively validates/repairs 109 // these. All valid fields are added to the result dictionary. Returns the 110 // repaired dictionary. Only on error returns NULL. 111 virtual scoped_ptr<base::DictionaryValue> MapObject( 112 const OncValueSignature& signature, 113 const base::DictionaryValue& onc_object, 114 bool* error) OVERRIDE; 115 116 // Pushes/pops the |field_name| to |path_|, otherwise like |Mapper::MapField|. 117 virtual scoped_ptr<base::Value> MapField( 118 const std::string& field_name, 119 const OncValueSignature& object_signature, 120 const base::Value& onc_value, 121 bool* found_unknown_field, 122 bool* error) OVERRIDE; 123 124 // Ignores nested errors in NetworkConfigurations and Certificates, otherwise 125 // like |Mapper::MapArray|. 126 virtual scoped_ptr<base::ListValue> MapArray( 127 const OncValueSignature& array_signature, 128 const base::ListValue& onc_array, 129 bool* nested_error) OVERRIDE; 130 131 // Pushes/pops the index to |path_|, otherwise like |Mapper::MapEntry|. 132 virtual scoped_ptr<base::Value> MapEntry(int index, 133 const OncValueSignature& signature, 134 const base::Value& onc_value, 135 bool* error) OVERRIDE; 136 137 // This is the default validation of objects/dictionaries. Validates 138 // |onc_object| according to |object_signature|. |result| must point to a 139 // dictionary into which the repaired fields are written. 140 bool ValidateObjectDefault(const OncValueSignature& object_signature, 141 const base::DictionaryValue& onc_object, 142 base::DictionaryValue* result); 143 144 // Validates/repairs the kRecommended array in |result| according to 145 // |object_signature| of the enclosing object. 146 bool ValidateRecommendedField(const OncValueSignature& object_signature, 147 base::DictionaryValue* result); 148 149 // Validates the ClientCert* fields in a VPN or EAP object. Only if 150 // |allow_cert_type_none| is true, the value "None" is allowed as 151 // ClientCertType. 152 bool ValidateClientCertFields(bool allow_cert_type_none, 153 base::DictionaryValue* result); 154 155 bool ValidateToplevelConfiguration(base::DictionaryValue* result); 156 bool ValidateNetworkConfiguration(base::DictionaryValue* result); 157 bool ValidateEthernet(base::DictionaryValue* result); 158 bool ValidateIPConfig(base::DictionaryValue* result); 159 bool ValidateWiFi(base::DictionaryValue* result); 160 bool ValidateVPN(base::DictionaryValue* result); 161 bool ValidateIPsec(base::DictionaryValue* result); 162 bool ValidateOpenVPN(base::DictionaryValue* result); 163 bool ValidateVerifyX509(base::DictionaryValue* result); 164 bool ValidateCertificatePattern(base::DictionaryValue* result); 165 bool ValidateProxySettings(base::DictionaryValue* result); 166 bool ValidateProxyLocation(base::DictionaryValue* result); 167 bool ValidateEAP(base::DictionaryValue* result); 168 bool ValidateCertificate(base::DictionaryValue* result); 169 170 bool FieldExistsAndHasNoValidValue( 171 const base::DictionaryValue& object, 172 const std::string& field_name, 173 const std::vector<const char*>& valid_values); 174 175 bool FieldExistsAndIsNotInRange(const base::DictionaryValue& object, 176 const std::string &field_name, 177 int lower_bound, 178 int upper_bound); 179 180 bool FieldExistsAndIsEmpty(const base::DictionaryValue& object, 181 const std::string& field_name); 182 183 bool RequireField(const base::DictionaryValue& dict, const std::string& key); 184 185 // Returns true if the GUID is unique or if the GUID is not a string 186 // and false otherwise. The function also adds the GUID to a set in 187 // order to identify duplicates. 188 bool CheckGuidIsUniqueAndAddToSet(const base::DictionaryValue& dict, 189 const std::string& kGUID, 190 std::set<std::string> *guids); 191 192 // Prohibit certificate patterns for device policy ONC so that an unmanaged 193 // user won't have a certificate presented for them involuntarily. 194 bool IsCertPatternInDevicePolicy(const std::string& cert_type); 195 196 // Prohibit global network configuration in user ONC imports. 197 bool IsGlobalNetworkConfigInUserImport( 198 const base::DictionaryValue& onc_object); 199 200 std::string MessageHeader(); 201 202 const bool error_on_unknown_field_; 203 const bool error_on_wrong_recommended_; 204 const bool error_on_missing_field_; 205 const bool managed_onc_; 206 207 ::onc::ONCSource onc_source_; 208 209 // The path of field names and indices to the current value. Indices 210 // are stored as strings in decimal notation. 211 std::vector<std::string> path_; 212 213 // Accumulates all network GUIDs during validation. Used to identify 214 // duplicate GUIDs. 215 std::set<std::string> network_guids_; 216 217 // Accumulates all certificate GUIDs during validation. Used to identify 218 // duplicate GUIDs. 219 std::set<std::string> certificate_guids_; 220 221 // Tracks if an error or warning occurred within validation initiated by 222 // function ValidateAndRepairObject. 223 bool error_or_warning_found_; 224 225 DISALLOW_COPY_AND_ASSIGN(Validator); 226 }; 227 228 } // namespace onc 229 } // namespace chromeos 230 231 #endif // CHROMEOS_NETWORK_ONC_ONC_VALIDATOR_H_ 232