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 #ifndef CHROMEOS_NETWORK_ONC_ONC_VALIDATOR_H_
6 #define CHROMEOS_NETWORK_ONC_ONC_VALIDATOR_H_
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"
18 class DictionaryValue
;
25 struct OncValueSignature
;
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)
31 // - a field name is found that is not part of the signature
32 // (controlled by flag |error_on_unknown_field|)
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|)
38 // - |managed_onc| is false and a field with name kRecommended is found
41 // - a required field is missing. Controlled by flag |error_on_missing_field|.
42 // If true this is an error. If false, a message is logged but no error or
43 // warning is flagged.
45 // If one of these invalid cases occurs and, in case of a controlling flag, that
46 // flag is true, then it is an error. The function ValidateAndRepairObject sets
47 // |result| to INVALID and returns NULL.
49 // Otherwise, a DeepCopy of the validated object is created, which contains
50 // all but the invalid fields and values.
52 // If one of the invalid cases occurs and the controlling flag is false, then
53 // it is a warning. The function ValidateAndRepairObject sets |result| to
54 // VALID_WITH_WARNINGS and returns the repaired copy.
56 // If no error occurred, |result| is set to VALID and an exact DeepCopy is
58 class CHROMEOS_EXPORT Validator
: public Mapper
{
66 // See the class comment.
67 Validator(bool error_on_unknown_field
,
68 bool error_on_wrong_recommended
,
69 bool error_on_missing_field
,
72 ~Validator() override
;
74 // Sets the ONC source to |source|. If not set, defaults to ONC_SOURCE_NONE.
75 // If the source is set to ONC_SOURCE_DEVICE_POLICY, validation additionally
77 // - only the network types Wifi and Ethernet are allowed
78 // - client certificate patterns are disallowed
79 void SetOncSource(::onc::ONCSource source
) {
83 // Validate the given |onc_object| according to |object_signature|. The
84 // |object_signature| has to be a pointer to one of the signatures in
85 // |onc_signature.h|. If an error is found, the function returns NULL and sets
86 // |result| to INVALID. If possible (no error encountered) a DeepCopy is
87 // created that contains all but the invalid fields and values and returns
88 // this "repaired" object. That means, if not handled as an error, then the
89 // following are dropped from the copy:
91 // - invalid field names in kRecommended arrays
92 // - kRecommended fields in an unmanaged ONC
93 // If any of these cases occurred, sets |result| to VALID_WITH_WARNINGS and
94 // otherwise to VALID.
95 // For details, see the class comment.
96 scoped_ptr
<base::DictionaryValue
> ValidateAndRepairObject(
97 const OncValueSignature
* object_signature
,
98 const base::DictionaryValue
& onc_object
,
102 // Overridden from Mapper:
103 // Compare |onc_value|s type with |onc_type| and validate/repair according to
104 // |signature|. On error returns NULL.
105 scoped_ptr
<base::Value
> MapValue(const OncValueSignature
& signature
,
106 const base::Value
& onc_value
,
107 bool* error
) override
;
109 // Dispatch to the right validation function according to
110 // |signature|. Iterates over all fields and recursively validates/repairs
111 // these. All valid fields are added to the result dictionary. Returns the
112 // repaired dictionary. Only on error returns NULL.
113 scoped_ptr
<base::DictionaryValue
> MapObject(
114 const OncValueSignature
& signature
,
115 const base::DictionaryValue
& onc_object
,
116 bool* error
) override
;
118 // Pushes/pops the |field_name| to |path_|, otherwise like |Mapper::MapField|.
119 scoped_ptr
<base::Value
> MapField(const std::string
& field_name
,
120 const OncValueSignature
& object_signature
,
121 const base::Value
& onc_value
,
122 bool* found_unknown_field
,
123 bool* error
) override
;
125 // Ignores nested errors in NetworkConfigurations and Certificates, otherwise
126 // like |Mapper::MapArray|.
127 scoped_ptr
<base::ListValue
> MapArray(const OncValueSignature
& array_signature
,
128 const base::ListValue
& onc_array
,
129 bool* nested_error
) override
;
131 // Pushes/pops the index to |path_|, otherwise like |Mapper::MapEntry|.
132 scoped_ptr
<base::Value
> MapEntry(int index
,
133 const OncValueSignature
& signature
,
134 const base::Value
& onc_value
,
135 bool* error
) override
;
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
);
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
);
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
152 bool ValidateClientCertFields(bool allow_cert_type_none
,
153 base::DictionaryValue
* result
);
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 ValidateThirdPartyVPN(base::DictionaryValue
* result
);
164 bool ValidateVerifyX509(base::DictionaryValue
* result
);
165 bool ValidateCertificatePattern(base::DictionaryValue
* result
);
166 bool ValidateGlobalNetworkConfiguration(base::DictionaryValue
* result
);
167 bool ValidateProxySettings(base::DictionaryValue
* result
);
168 bool ValidateProxyLocation(base::DictionaryValue
* result
);
169 bool ValidateEAP(base::DictionaryValue
* result
);
170 bool ValidateCertificate(base::DictionaryValue
* result
);
172 bool IsValidValue(const std::string
& field_value
,
173 const std::vector
<const char*>& valid_values
);
174 bool FieldExistsAndHasNoValidValue(
175 const base::DictionaryValue
& object
,
176 const std::string
& field_name
,
177 const std::vector
<const char*>& valid_values
);
179 bool FieldExistsAndIsNotInRange(const base::DictionaryValue
& object
,
180 const std::string
&field_name
,
184 bool FieldExistsAndIsEmpty(const base::DictionaryValue
& object
,
185 const std::string
& field_name
);
187 bool ListFieldContainsValidValues(
188 const base::DictionaryValue
& object
,
189 const std::string
& field_name
,
190 const std::vector
<const char*>& valid_values
);
192 bool ValidateSSIDAndHexSSID(base::DictionaryValue
* object
);
194 // Returns true if |key| is a key of |dict|. Otherwise, returns false and,
195 // depending on |error_on_missing_field_|, logs a message and sets
196 // |error_or_warning_found_|.
197 bool RequireField(const base::DictionaryValue
& dict
, const std::string
& key
);
199 // Returns true if the GUID is unique or if the GUID is not a string
200 // and false otherwise. The function also adds the GUID to a set in
201 // order to identify duplicates.
202 bool CheckGuidIsUniqueAndAddToSet(const base::DictionaryValue
& dict
,
203 const std::string
& kGUID
,
204 std::set
<std::string
> *guids
);
206 // Prohibit certificate patterns for device policy ONC so that an unmanaged
207 // user won't have a certificate presented for them involuntarily.
208 bool IsCertPatternInDevicePolicy(const std::string
& cert_type
);
210 // Prohibit global network configuration in user ONC imports.
211 bool IsGlobalNetworkConfigInUserImport(
212 const base::DictionaryValue
& onc_object
);
214 std::string
MessageHeader();
216 const bool error_on_unknown_field_
;
217 const bool error_on_wrong_recommended_
;
218 const bool error_on_missing_field_
;
219 const bool managed_onc_
;
221 ::onc::ONCSource onc_source_
;
223 // The path of field names and indices to the current value. Indices
224 // are stored as strings in decimal notation.
225 std::vector
<std::string
> path_
;
227 // Accumulates all network GUIDs during validation. Used to identify
229 std::set
<std::string
> network_guids_
;
231 // Accumulates all certificate GUIDs during validation. Used to identify
233 std::set
<std::string
> certificate_guids_
;
235 // Tracks if an error or warning occurred within validation initiated by
236 // function ValidateAndRepairObject.
237 bool error_or_warning_found_
;
239 DISALLOW_COPY_AND_ASSIGN(Validator
);
243 } // namespace chromeos
245 #endif // CHROMEOS_NETWORK_ONC_ONC_VALIDATOR_H_