configuration_policy_handler_chromeos.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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#include "chrome/browser/chromeos/policy/configuration_policy_handler_chromeos.h"
6
7#include <string>
8
9#include "base/json/json_reader.h"
10#include "base/json/json_writer.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/prefs/pref_value_map.h"
13#include "base/string_util.h"
14#include "base/values.h"
15#include "chrome/browser/policy/policy_error_map.h"
16#include "chrome/browser/policy/policy_map.h"
17#include "chrome/browser/ui/ash/chrome_launcher_prefs.h"
18#include "chrome/common/pref_names.h"
19#include "chromeos/network/onc/onc_constants.h"
20#include "chromeos/network/onc/onc_signature.h"
21#include "chromeos/network/onc/onc_utils.h"
22#include "chromeos/network/onc/onc_validator.h"
23#include "grit/generated_resources.h"
24#include "policy/policy_constants.h"
25
26namespace onc = chromeos::onc;
27
28namespace policy {
29
30// static
31NetworkConfigurationPolicyHandler*
32NetworkConfigurationPolicyHandler::CreateForUserPolicy() {
33  return new NetworkConfigurationPolicyHandler(
34      key::kOpenNetworkConfiguration, onc::ONC_SOURCE_USER_POLICY);
35}
36
37// static
38NetworkConfigurationPolicyHandler*
39NetworkConfigurationPolicyHandler::CreateForDevicePolicy() {
40  return new NetworkConfigurationPolicyHandler(
41      key::kDeviceOpenNetworkConfiguration, onc::ONC_SOURCE_DEVICE_POLICY);
42}
43
44NetworkConfigurationPolicyHandler::~NetworkConfigurationPolicyHandler() {}
45
46bool NetworkConfigurationPolicyHandler::CheckPolicySettings(
47    const PolicyMap& policies,
48    PolicyErrorMap* errors) {
49  const base::Value* value;
50  if (!CheckAndGetValue(policies, errors, &value))
51    return false;
52
53  if (value) {
54    std::string onc_blob;
55    value->GetAsString(&onc_blob);
56    scoped_ptr<base::DictionaryValue> root_dict =
57        onc::ReadDictionaryFromJson(onc_blob);
58    if (root_dict.get() == NULL) {
59      errors->AddError(policy_name(), IDS_POLICY_NETWORK_CONFIG_PARSE_FAILED);
60      return false;
61    }
62
63    // Validate the ONC dictionary. We are liberal and ignore unknown field
64    // names and ignore invalid field names in kRecommended arrays.
65    onc::Validator validator(false,  // Ignore unknown fields.
66                             false,  // Ignore invalid recommended field names.
67                             true,  // Fail on missing fields.
68                             true);  // Validate for managed ONC
69    validator.SetOncSource(onc_source_);
70
71    // ONC policies are always unencrypted.
72    onc::Validator::Result validation_result;
73    root_dict = validator.ValidateAndRepairObject(
74        &onc::kToplevelConfigurationSignature, *root_dict, &validation_result);
75    if (validation_result == onc::Validator::VALID_WITH_WARNINGS) {
76      errors->AddError(policy_name(),
77                       IDS_POLICY_NETWORK_CONFIG_IMPORT_PARTIAL);
78    } else if (validation_result == onc::Validator::INVALID) {
79      errors->AddError(policy_name(), IDS_POLICY_NETWORK_CONFIG_IMPORT_FAILED);
80    }
81
82    // In any case, don't reject the policy as some networks or certificates
83    // could still be applied.
84  }
85
86  return true;
87}
88
89void NetworkConfigurationPolicyHandler::ApplyPolicySettings(
90    const PolicyMap& policies,
91    PrefValueMap* prefs) {
92  // Network policy is read directly from the provider and injected into
93  // NetworkLibrary, so no need to convert the policy settings into prefs.
94}
95
96void NetworkConfigurationPolicyHandler::PrepareForDisplaying(
97    PolicyMap* policies) const {
98  const PolicyMap::Entry* entry = policies->Get(policy_name());
99  if (!entry)
100    return;
101  base::Value* sanitized_config = SanitizeNetworkConfig(entry->value);
102  if (!sanitized_config)
103    sanitized_config = base::Value::CreateNullValue();
104
105  policies->Set(policy_name(), entry->level, entry->scope, sanitized_config);
106}
107
108NetworkConfigurationPolicyHandler::NetworkConfigurationPolicyHandler(
109    const char* policy_name,
110    chromeos::onc::ONCSource onc_source)
111    : TypeCheckingPolicyHandler(policy_name, base::Value::TYPE_STRING),
112      onc_source_(onc_source) {
113}
114
115// static
116base::Value* NetworkConfigurationPolicyHandler::SanitizeNetworkConfig(
117    const base::Value* config) {
118  std::string json_string;
119  if (!config->GetAsString(&json_string))
120    return NULL;
121
122  scoped_ptr<base::DictionaryValue> toplevel_dict =
123      onc::ReadDictionaryFromJson(json_string);
124  if (!toplevel_dict)
125    return NULL;
126
127  // Placeholder to insert in place of the filtered setting.
128  const char kPlaceholder[] = "********";
129
130  toplevel_dict = onc::MaskCredentialsInOncObject(
131      onc::kToplevelConfigurationSignature,
132      *toplevel_dict,
133      kPlaceholder);
134
135  base::JSONWriter::WriteWithOptions(toplevel_dict.get(),
136                                     base::JSONWriter::OPTIONS_DO_NOT_ESCAPE |
137                                         base::JSONWriter::OPTIONS_PRETTY_PRINT,
138                                     &json_string);
139  return base::Value::CreateStringValue(json_string);
140}
141
142PinnedLauncherAppsPolicyHandler::PinnedLauncherAppsPolicyHandler()
143    : ExtensionListPolicyHandler(key::kPinnedLauncherApps,
144                                 prefs::kPinnedLauncherApps,
145                                 false) {}
146
147PinnedLauncherAppsPolicyHandler::~PinnedLauncherAppsPolicyHandler() {}
148
149void PinnedLauncherAppsPolicyHandler::ApplyPolicySettings(
150    const PolicyMap& policies,
151    PrefValueMap* prefs) {
152  PolicyErrorMap errors;
153  const base::Value* policy_value = policies.GetValue(policy_name());
154  const base::ListValue* policy_list = NULL;
155  if (policy_value && policy_value->GetAsList(&policy_list) && policy_list) {
156    base::ListValue* pinned_apps_list = new base::ListValue();
157    for (base::ListValue::const_iterator entry(policy_list->begin());
158         entry != policy_list->end(); ++entry) {
159      std::string id;
160      if ((*entry)->GetAsString(&id)) {
161        base::DictionaryValue* app_dict = new base::DictionaryValue();
162        app_dict->SetString(ash::kPinnedAppsPrefAppIDPath, id);
163        pinned_apps_list->Append(app_dict);
164      }
165    }
166    prefs->SetValue(pref_path(), pinned_apps_list);
167  }
168}
169
170}  // namespace policy
171