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