onc_validator.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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
17namespace base {
18class DictionaryValue;
19class Value;
20}
21
22namespace chromeos {
23namespace onc {
24
25struct 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.
56class 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
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  bool ValidateToplevelConfiguration(base::DictionaryValue* result);
150  bool ValidateNetworkConfiguration(base::DictionaryValue* result);
151  bool ValidateEthernet(base::DictionaryValue* result);
152  bool ValidateIPConfig(base::DictionaryValue* result);
153  bool ValidateWiFi(base::DictionaryValue* result);
154  bool ValidateVPN(base::DictionaryValue* result);
155  bool ValidateIPsec(base::DictionaryValue* result);
156  bool ValidateOpenVPN(base::DictionaryValue* result);
157  bool ValidateVerifyX509(base::DictionaryValue* result);
158  bool ValidateCertificatePattern(base::DictionaryValue* result);
159  bool ValidateProxySettings(base::DictionaryValue* result);
160  bool ValidateProxyLocation(base::DictionaryValue* result);
161  bool ValidateEAP(base::DictionaryValue* result);
162  bool ValidateCertificate(base::DictionaryValue* result);
163
164  bool FieldExistsAndHasNoValidValue(const base::DictionaryValue& object,
165                                     const std::string &field_name,
166                                     const char** valid_values);
167
168  bool FieldExistsAndIsNotInRange(const base::DictionaryValue& object,
169                                  const std::string &field_name,
170                                  int lower_bound,
171                                  int upper_bound);
172
173  bool FieldExistsAndIsEmpty(const base::DictionaryValue& object,
174                             const std::string& field_name);
175
176  bool RequireField(const base::DictionaryValue& dict, const std::string& key);
177
178  // Returns true if the GUID is unique or if the GUID is not a string
179  // and false otherwise. The function also adds the GUID to a set in
180  // order to identify duplicates.
181  bool CheckGuidIsUniqueAndAddToSet(const base::DictionaryValue& dict,
182                                    const std::string& kGUID,
183                                    std::set<std::string> *guids);
184
185  // Prohibit certificate patterns for device policy ONC so that an unmanaged
186  // user won't have a certificate presented for them involuntarily.
187  bool IsCertPatternInDevicePolicy(const std::string& cert_type);
188
189  // Prohibit global network configuration in user ONC imports.
190  bool IsGlobalNetworkConfigInUserImport(
191      const base::DictionaryValue& onc_object);
192
193  std::string MessageHeader();
194
195  const bool error_on_unknown_field_;
196  const bool error_on_wrong_recommended_;
197  const bool error_on_missing_field_;
198  const bool managed_onc_;
199
200  ::onc::ONCSource onc_source_;
201
202  // The path of field names and indices to the current value. Indices
203  // are stored as strings in decimal notation.
204  std::vector<std::string> path_;
205
206  // Accumulates all network GUIDs during validation. Used to identify
207  // duplicate GUIDs.
208  std::set<std::string> network_guids_;
209
210  // Accumulates all certificate GUIDs during validation. Used to identify
211  // duplicate GUIDs.
212  std::set<std::string> certificate_guids_;
213
214  // Tracks if an error or warning occurred within validation initiated by
215  // function ValidateAndRepairObject.
216  bool error_or_warning_found_;
217
218  DISALLOW_COPY_AND_ASSIGN(Validator);
219};
220
221}  // namespace onc
222}  // namespace chromeos
223
224#endif  // CHROMEOS_NETWORK_ONC_ONC_VALIDATOR_H_
225