Home | History | Annotate | Download | only in onc_validator
      1 // Copyright (c) 2011 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 <cstdio>
      6 #include <iostream>
      7 
      8 #include "base/basictypes.h"
      9 #include "base/command_line.h"
     10 #include "base/files/file_path.h"
     11 #include "base/json/json_file_value_serializer.h"
     12 #include "base/logging.h"
     13 #include "base/values.h"
     14 #include "chromeos/network/onc/onc_signature.h"
     15 #include "chromeos/network/onc/onc_validator.h"
     16 
     17 // Command line switches.
     18 const char kSwitchErrorOnUnknownField[] = "error-on-unknown-field";
     19 const char kSwitchErrorOnWrongRecommended[] = "error-on-wrong-recommended";
     20 const char kSwitchErrorOnMissingField[] = "error-on-missing-field";
     21 const char kSwitchManagedOnc[] = "managed-onc";
     22 const char kSwitchUserPolicy[] = "user-policy";
     23 const char kSwitchDevicePolicy[] = "device-policy";
     24 const char kSwitchUserImport[] = "user-import";
     25 
     26 const char* kSwitches[] = {
     27   kSwitchErrorOnUnknownField,
     28   kSwitchErrorOnWrongRecommended,
     29   kSwitchErrorOnMissingField,
     30   kSwitchManagedOnc,
     31   kSwitchUserPolicy,
     32   kSwitchDevicePolicy,
     33   kSwitchUserImport
     34 };
     35 
     36 // Return codes.
     37 enum ReturnCode {
     38   kStatusValid = 0,
     39   kStatusWarnings = 1,
     40   kStatusInvalid = 2,
     41   kStatusJsonError = 3,
     42   kStatusArgumentError = 4,
     43 };
     44 
     45 const char kToplevelConfiguration[] = "ToplevelConfiguration";
     46 const char kNetworkConfiguration[] = "NetworkConfiguration";
     47 const char kCertificate[] = "Certificate";
     48 const char* kTypes[] = {
     49   kToplevelConfiguration,
     50   kNetworkConfiguration,
     51   kCertificate
     52 };
     53 
     54 void PrintHelp() {
     55   fprintf(stderr,
     56           "Usage:\n"
     57           "  onc_validator [OPTION]... [TYPE] onc_file\n"
     58           "\n"
     59           "Valid TYPEs are:\n");
     60   for (size_t i = 0; i < arraysize(kTypes); ++i)
     61     fprintf(stderr, "  %s\n", kTypes[i]);
     62 
     63   fprintf(stderr,
     64           "\n"
     65           "Valid OPTIONs are:\n");
     66   for (size_t i = 0; i < arraysize(kSwitches); ++i)
     67     fprintf(stderr, "  --%s\n", kSwitches[i]);
     68 
     69   fprintf(stderr,
     70           "\n"
     71           "Exit status is one of:\n"
     72           "  %i  File is valid without warnings.\n"
     73           "  %i  File is valid with warnings,\n"
     74           "       i.e. there were errors which were degraded to warnings.\n"
     75           "  %i  File is invalid.\n"
     76           "  %i  File couldn't be read or is not a valid JSON dictionary.\n"
     77           "  %i  Some command line arguments are wrong.\n",
     78           kStatusValid,
     79           kStatusWarnings,
     80           kStatusInvalid,
     81           kStatusJsonError,
     82           kStatusArgumentError);
     83 }
     84 
     85 scoped_ptr<base::DictionaryValue> ReadDictionary(std::string filename) {
     86   base::FilePath path(filename);
     87   JSONFileValueSerializer serializer(path);
     88   serializer.set_allow_trailing_comma(true);
     89 
     90   base::DictionaryValue* dict = NULL;
     91 
     92   std::string json_error;
     93   base::Value* value = serializer.Deserialize(NULL, &json_error);
     94   if (!value) {
     95     LOG(ERROR) << "Couldn't json-deserialize file '" << filename
     96                << "': " << json_error;
     97     return make_scoped_ptr(dict);
     98   }
     99 
    100   if (!value->GetAsDictionary(&dict)) {
    101     LOG(ERROR) << "File '" << filename
    102                << "' does not contain a dictionary as expected, but type "
    103                << value->GetType();
    104   }
    105 
    106   return make_scoped_ptr(dict);
    107 }
    108 
    109 int main(int argc, const char* argv[]) {
    110   CommandLine::Init(argc, argv);
    111 
    112   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
    113   CommandLine::StringVector args = command_line.GetArgs();
    114   if (args.size() != 2) {
    115     PrintHelp();
    116     return kStatusArgumentError;
    117   }
    118 
    119   scoped_ptr<base::DictionaryValue> onc_object = ReadDictionary(args[1]);
    120 
    121   if (!onc_object)
    122     return kStatusJsonError;
    123 
    124   chromeos::onc::Validator validator(
    125       command_line.HasSwitch(kSwitchErrorOnUnknownField),
    126       command_line.HasSwitch(kSwitchErrorOnWrongRecommended),
    127       command_line.HasSwitch(kSwitchErrorOnMissingField),
    128       command_line.HasSwitch(kSwitchManagedOnc));
    129 
    130   if (command_line.HasSwitch(kSwitchUserPolicy))
    131     validator.SetOncSource(chromeos::onc::ONC_SOURCE_USER_POLICY);
    132   else if (command_line.HasSwitch(kSwitchDevicePolicy))
    133     validator.SetOncSource(chromeos::onc::ONC_SOURCE_DEVICE_POLICY);
    134   else if (command_line.HasSwitch(kSwitchUserImport))
    135     validator.SetOncSource(chromeos::onc::ONC_SOURCE_USER_IMPORT);
    136 
    137   std::string type_arg(args[0]);
    138   const chromeos::onc::OncValueSignature* signature = NULL;
    139   if (type_arg == kToplevelConfiguration) {
    140     signature = &chromeos::onc::kToplevelConfigurationSignature;
    141   } else if (type_arg == kNetworkConfiguration) {
    142     signature = &chromeos::onc::kNetworkConfigurationSignature;
    143   } else if (type_arg == kCertificate) {
    144     signature = &chromeos::onc::kCertificateSignature;
    145   } else {
    146     LOG(ERROR) << "Unknown ONC type '" << type_arg << "'";
    147     return kStatusArgumentError;
    148   }
    149 
    150   chromeos::onc::Validator::Result result;
    151   validator.ValidateAndRepairObject(signature, *onc_object, &result);
    152 
    153   switch(result) {
    154     case chromeos::onc::Validator::VALID:
    155       return kStatusValid;
    156     case chromeos::onc::Validator::VALID_WITH_WARNINGS:
    157       return kStatusWarnings;
    158     case chromeos::onc::Validator::INVALID:
    159       return kStatusInvalid;
    160     default:
    161       CHECK(false);
    162   }
    163 }
    164