blob: 028f9381e4ed6940e7d0d324f85217a5f4881504 [file] [log] [blame]
Bartosz Fabianowskic4ee8bf2012-01-25 16:31:26 +01001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Julian Pastarmov2638fbc2011-07-20 14:30:46 +02002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "device_policy_impl.h"
6
7#include <openssl/evp.h>
8#include <openssl/x509.h>
9
10#include <string>
11
12#include "base/basictypes.h"
13#include "base/file_path.h"
14#include "base/file_util.h"
15#include "base/logging.h"
16#include "bindings/chrome_device_policy.pb.h"
17#include "bindings/device_management_backend.pb.h"
18
19namespace policy {
20
21namespace {
22const char kPolicyPath[] = "/var/lib/whitelist/policy";
23const char kPublicKeyPath[] = "/var/lib/whitelist/owner.key";
24
25// Reads the public key used to sign the policy from |key_file| and stores it
26// in |public_key|. Returns true on success.
27bool ReadPublicKeyFromFile(const FilePath& key_file, std::string* public_key) {
28 if (!file_util::PathExists(key_file))
29 return false;
30 public_key->clear();
31 if (!file_util::ReadFileToString(key_file, public_key) ||
32 public_key->empty()) {
33 LOG(ERROR) << "Could not read public key off disk";
34 return false;
35 }
36 return true;
37}
38
39// Verifies that the |signed_data| has correct |signature| with |public_key|.
40bool VerifySignature(std::string& signed_data,
41 std::string& signature,
42 std::string& public_key) {
43 EVP_MD_CTX ctx;
44 EVP_MD_CTX_init(&ctx);
45
46 const EVP_MD* digest = EVP_sha1();
47
48 char* key = const_cast<char*>(public_key.data());
49 BIO* bio = BIO_new_mem_buf(key, public_key.length());
50 if (!bio) {
51 EVP_MD_CTX_cleanup(&ctx);
52 return false;
53 }
54
55 EVP_PKEY* public_key_ssl = d2i_PUBKEY_bio(bio, NULL);
56 if (!public_key_ssl) {
57 BIO_free_all(bio);
58 EVP_MD_CTX_cleanup(&ctx);
59 return false;
60 }
61
62 const unsigned char* sig =
63 reinterpret_cast<const unsigned char*>(signature.data());
64 int rv = EVP_VerifyInit_ex(&ctx, digest, NULL);
65 if (rv == 1) {
66 EVP_VerifyUpdate(&ctx, signed_data.data(), signed_data.length());
67 rv = EVP_VerifyFinal(&ctx,
68 sig, signature.length(),
69 public_key_ssl);
70 }
71
72 EVP_PKEY_free(public_key_ssl);
73 BIO_free_all(bio);
74 EVP_MD_CTX_cleanup(&ctx);
75
76 return rv == 1;
77}
78
79} // namespace
80
81DevicePolicyImpl::DevicePolicyImpl()
82 : policy_path_(kPolicyPath),
83 keyfile_path_(kPublicKeyPath) {
84}
85
86DevicePolicyImpl::~DevicePolicyImpl() {
87}
88
89bool DevicePolicyImpl::LoadPolicy() {
90 if (!VerifyPolicyFiles()) {
Julian Pastarmov2638fbc2011-07-20 14:30:46 +020091 return false;
92 }
93
94 std::string polstr;
95 if (!file_util::ReadFileToString(policy_path_, &polstr) || polstr.empty()) {
96 LOG(ERROR) << "Could not read policy off disk";
97 return false;
98 }
99 if (!policy_.ParseFromString(polstr) || !policy_.has_policy_data()) {
100 LOG(ERROR) << "Policy on disk could not be parsed!";
101 return false;
102 }
Bartosz Fabianowskic4ee8bf2012-01-25 16:31:26 +0100103 policy_data_.ParseFromString(policy_.policy_data());
104 if (!policy_data_.has_policy_value()) {
Julian Pastarmov2638fbc2011-07-20 14:30:46 +0200105 LOG(ERROR) << "Policy on disk could not be parsed!";
106 return false;
107 }
108
109 // Make sure the signature is still valid.
110 if (!VerifyPolicySignature()) {
111 LOG(ERROR) << "Policy signature verification failed!";
112 return false;
113 }
114
Bartosz Fabianowskic4ee8bf2012-01-25 16:31:26 +0100115 device_policy_.ParseFromString(policy_data_.policy_value());
Julian Pastarmov2638fbc2011-07-20 14:30:46 +0200116 return true;
117}
118
119// Writes the value of the PolicyRefreshRate policy in |rate|. Returns
120// true on success.
121bool DevicePolicyImpl::GetPolicyRefreshRate(int* rate) const {
122 if (!device_policy_.has_device_policy_refresh_rate())
123 return false;
124 *rate = static_cast<int>(
125 device_policy_.device_policy_refresh_rate().device_policy_refresh_rate());
126 return true;
127}
128
129// Writes the value of the UserWhitelist policy in |user_whitelist|. Returns
130// true on success.
131bool DevicePolicyImpl::GetUserWhitelist(
132 std::vector<std::string>* user_whitelist) const {
133 if (!device_policy_.has_user_whitelist())
134 return false;
135 const enterprise_management::UserWhitelistProto& proto =
136 device_policy_.user_whitelist();
137 user_whitelist->clear();
138 for (int i = 0; i < proto.user_whitelist_size(); i++)
139 user_whitelist->push_back(proto.user_whitelist(i));
140 return true;
141}
142
143// Writes the value of the GuestModeEnabled policy in |guest_mode_enabled|.
144// Returns true on success.
145bool DevicePolicyImpl::GetGuestModeEnabled(bool* guest_mode_enabled) const {
146 if (!device_policy_.has_guest_mode_enabled())
147 return false;
148 *guest_mode_enabled =
149 device_policy_.guest_mode_enabled().guest_mode_enabled();
150 return true;
151}
152
153// Writes the value of the CameraEnabled policy in |camera_enabled|. Returns
154// true on success.
155bool DevicePolicyImpl::GetCameraEnabled(bool* camera_enabled) const {
156 if (!device_policy_.has_camera_enabled())
157 return false;
158 *camera_enabled = device_policy_.camera_enabled().camera_enabled();
159 return true;
160}
161
162// Writes the value of the ShowUserNamesOnSignIn policy in |show_usernames|.
163// Returns true on success.
164bool DevicePolicyImpl::GetShowUserNames(bool* show_user_names) const {
165 if (!device_policy_.has_show_user_names())
166 return false;
167 *show_user_names = device_policy_.show_user_names().show_user_names();
168 return true;
169}
170
171// Writes the value of the DataRoamingEnabled policy in |data_roaming_enabled|
172// Returns true on success.
173bool DevicePolicyImpl::GetDataRoamingEnabled(bool* data_roaming_enabled) const {
174 if (!device_policy_.has_data_roaming_enabled())
175 return false;
176 *data_roaming_enabled =
177 device_policy_.data_roaming_enabled().data_roaming_enabled();
178 return true;
179}
180
181// Writes the value of the AllowNewUSer policy in |allow_new_user|. Returns
182// true on success.
183bool DevicePolicyImpl::GetAllowNewUsers(bool* allow_new_users) const {
184 if (!device_policy_.has_allow_new_users())
185 return false;
186 *allow_new_users = device_policy_.allow_new_users().allow_new_users();
187 return true;
188}
189
190// Writes the value of the MetricsEnabled policy in |metrics_enabled|. Returns
191// true on success.
192bool DevicePolicyImpl::GetMetricsEnabled(bool* metrics_enabled) const {
193 if (!device_policy_.has_metrics_enabled())
194 return false;
195 *metrics_enabled = device_policy_.metrics_enabled().metrics_enabled();
196 return true;
197}
198
Bartosz Fabianowskia6732cd2012-02-07 11:54:21 +0100199// Writes the value of ReportVersionInfo policy in |report_version_info|.
200// Returns true on success.
201bool DevicePolicyImpl::GetReportVersionInfo(bool* report_version_info) const {
202 if (!device_policy_.has_device_reporting())
203 return false;
204
205 const enterprise_management::DeviceReportingProto& proto =
206 device_policy_.device_reporting();
207 if (!proto.has_report_version_info())
208 return false;
209
210 *report_version_info = proto.report_version_info();
211 return true;
212}
213
214// Writes the value of ReportActivityTimes policy in |report_activity_times|.
215// Returns true on success.
216bool DevicePolicyImpl::GetReportActivityTimes(
217 bool* report_activity_times) const {
218 if (!device_policy_.has_device_reporting())
219 return false;
220
221 const enterprise_management::DeviceReportingProto& proto =
222 device_policy_.device_reporting();
223 if (!proto.has_report_activity_times())
224 return false;
225
226 *report_activity_times = proto.report_activity_times();
227 return true;
228}
229
230// Writes the value of ReportBootMode policy in |report_boot_mode|. Returns
231// true on success.
232bool DevicePolicyImpl::GetReportBootMode(bool* report_boot_mode) const {
233 if (!device_policy_.has_device_reporting())
234 return false;
235
236 const enterprise_management::DeviceReportingProto& proto =
237 device_policy_.device_reporting();
238 if (!proto.has_report_boot_mode())
239 return false;
240
241 *report_boot_mode = proto.report_boot_mode();
242 return true;
243}
244
Bartosz Fabianowski43bd0ad2012-02-15 17:06:01 -0800245// Writes the value of the EphemeralUsersEnabled policy in
246// |ephemeral_users_enabled|. Returns true on success.
247bool DevicePolicyImpl::GetEphemeralUsersEnabled(
248 bool* ephemeral_users_enabled) const {
249 if (!device_policy_.has_ephemeral_users_enabled())
Bartosz Fabianowskia6732cd2012-02-07 11:54:21 +0100250 return false;
Bartosz Fabianowski43bd0ad2012-02-15 17:06:01 -0800251 *ephemeral_users_enabled =
252 device_policy_.ephemeral_users_enabled().ephemeral_users_enabled();
Bartosz Fabianowskia6732cd2012-02-07 11:54:21 +0100253 return true;
254}
255
Julian Pastarmov2638fbc2011-07-20 14:30:46 +0200256// Writes the value of the ProxyMode policy in |proxy_mode|. Returns true on
257// success.
258bool DevicePolicyImpl::GetProxyMode(std::string* proxy_mode) const {
259 if (!device_policy_.has_device_proxy_settings())
260 return false;
261
262 const enterprise_management::DeviceProxySettingsProto& proto =
263 device_policy_.device_proxy_settings();
264 if (!proto.has_proxy_mode())
265 return false;
266
267 *proxy_mode = proto.proxy_mode();
268 return true;
269}
270
271// Writes the value of the ProxyServer policy in |proxy_server|. Returns true
272// on success.
273bool DevicePolicyImpl::GetProxyServer(std::string* proxy_server) const {
274 if (!device_policy_.has_device_proxy_settings())
275 return false;
276
277 const enterprise_management::DeviceProxySettingsProto& proto =
278 device_policy_.device_proxy_settings();
279 if (!proto.has_proxy_server())
280 return false;
281
282 *proxy_server = proto.proxy_server();
283 return true;
284}
285
286// Writes the value of the ProxyPacUrl policy in |proxy_pac|. Returns true on
287// success.
288bool DevicePolicyImpl::GetProxyPacUrl(std::string* proxy_pac) const {
289 if (!device_policy_.has_device_proxy_settings())
290 return false;
291
292 const enterprise_management::DeviceProxySettingsProto& proto =
293 device_policy_.device_proxy_settings();
294 if (!proto.has_proxy_pac_url())
295 return false;
296
297 *proxy_pac = proto.proxy_pac_url();
298 return true;
299}
300
301// Writes the value of the ProxyBypassList policy in |proxy_bypass_list|.
302// Returns true on success.
303bool DevicePolicyImpl::GetProxyBypassList(
304 std::string* proxy_bypass_list) const {
305 if (!device_policy_.has_device_proxy_settings())
306 return false;
307
308 const enterprise_management::DeviceProxySettingsProto& proto =
309 device_policy_.device_proxy_settings();
310 if (!proto.has_proxy_bypass_list())
311 return false;
312
313 *proxy_bypass_list = proto.proxy_bypass_list();
314 return true;
315}
316
Patrick Dubroy9d979cb2011-08-01 15:52:35 +0200317// Writes the value of the release channel policy in |release_channel|.
318// Returns true on success.
319bool DevicePolicyImpl::GetReleaseChannel(
320 std::string* release_channel) const {
321 if (!device_policy_.has_release_channel())
322 return false;
323
324 const enterprise_management::ReleaseChannelProto& proto =
325 device_policy_.release_channel();
326 if (!proto.has_release_channel())
327 return false;
328
329 *release_channel = proto.release_channel();
330 return true;
331}
332
Jay Srinivasancab5d3e2012-03-19 11:44:48 -0700333// Writes the value of the update_disabled policy in |update_disabled|.
334// Returns true on success.
335bool DevicePolicyImpl::GetUpdateDisabled(
336 bool* update_disabled) const {
337 if (!device_policy_.has_auto_update_settings())
338 return false;
339
340 const enterprise_management::AutoUpdateSettingsProto& proto =
341 device_policy_.auto_update_settings();
342 if (!proto.has_update_disabled())
343 return false;
344
345 *update_disabled = proto.update_disabled();
346 return true;
347}
348
349// Writes the value of the target_version_prefix policy in
350// |target_version_prefix|. Returns true on success.
351bool DevicePolicyImpl::GetTargetVersionPrefix(
352 std::string* target_version_prefix) const {
353 if (!device_policy_.has_auto_update_settings())
354 return false;
355
356 const enterprise_management::AutoUpdateSettingsProto& proto =
357 device_policy_.auto_update_settings();
358 if (!proto.has_target_version_prefix())
359 return false;
360
361 *target_version_prefix = proto.target_version_prefix();
362 return true;
363}
364
Jay Srinivasand7c86ae2012-05-31 19:24:56 -0700365// Writes the value of the scatter_factor_in_seconds policy in
366// |scatter_factor_in_seconds|. Returns true on success.
367bool DevicePolicyImpl::GetScatterFactorInSeconds(
368 int64* scatter_factor_in_seconds) const {
369 if (!device_policy_.has_auto_update_settings())
370 return false;
371
372 const enterprise_management::AutoUpdateSettingsProto& proto =
373 device_policy_.auto_update_settings();
374 if (!proto.has_scatter_factor_in_seconds())
375 return false;
376
377 *scatter_factor_in_seconds = proto.scatter_factor_in_seconds();
378 return true;
379}
380
Bartosz Fabianowskia6732cd2012-02-07 11:54:21 +0100381// Writes the value of the OpenNetworkConfiguration policy in
382// |open_network_configuration|. Returns true on success.
383bool DevicePolicyImpl::GetOpenNetworkConfiguration(
384 std::string* open_network_configuration) const {
385 if (!device_policy_.has_open_network_configuration())
386 return false;
387
388 const enterprise_management::DeviceOpenNetworkConfigurationProto& proto =
389 device_policy_.open_network_configuration();
390 if (!proto.has_open_network_configuration())
391 return false;
392
393 *open_network_configuration = proto.open_network_configuration();
394 return true;
395}
396
Bartosz Fabianowskic4ee8bf2012-01-25 16:31:26 +0100397// Writes the name of the device owner in |owner|. For enterprise enrolled
398// devices, this will be an empty string.
399// Returns true on success.
400bool DevicePolicyImpl::GetOwner(std::string* owner) const {
401 // The device is enterprise enrolled iff a request token exists.
402 if (policy_data_.has_request_token()) {
403 *owner = "";
404 return true;
405 }
406 if (!policy_data_.has_username())
407 return false;
408 *owner = policy_data_.username();
409 return true;
410}
411
Julian Pastarmov2638fbc2011-07-20 14:30:46 +0200412bool DevicePolicyImpl::VerifyPolicyFiles() {
413 // Both the policy and its signature have to exist.
414 if (!file_util::PathExists(policy_path_) ||
415 !file_util::PathExists(keyfile_path_)) {
Julian Pastarmov2638fbc2011-07-20 14:30:46 +0200416 return false;
417 }
418
419 // Check if the policy and signature file is owned by root.
420 struct stat file_stat;
421 stat(policy_path_.value().c_str(), &file_stat);
422 if (file_stat.st_uid != 0) {
423 LOG(ERROR) << "Policy file is not owned by root!";
424 return false;
425 }
426 stat(keyfile_path_.value().c_str(), &file_stat);
427 if (file_stat.st_uid != 0) {
428 LOG(ERROR) << "Policy signature file is not owned by root!";
429 return false;
430 }
431 return true;
432}
433
434bool DevicePolicyImpl::VerifyPolicySignature() {
435 if (policy_.has_policy_data_signature()) {
436 std::string policy_data = policy_.policy_data();
437 std::string policy_data_signature = policy_.policy_data_signature();
438 std::string public_key;
439 if (!ReadPublicKeyFromFile(FilePath(keyfile_path_), &public_key)) {
440 LOG(ERROR) << "Could not read owner key off disk";
441 return false;
442 }
443 if (!VerifySignature(policy_data, policy_data_signature, public_key)) {
444 LOG(ERROR) << "Signature does not match the data or can not be verified!";
445 return false;
446 }
447 return true;
448 }
449 LOG(ERROR) << "The policy blob is not signed!";
450 return false;
451}
452
453} // namespace policy
454