xref: /aosp_15_r20/external/libbrillo/policy/device_policy_impl.cc (revision 1a96fba65179ea7d3f56207137718607415c5953)
1*1a96fba6SXin Li // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2*1a96fba6SXin Li // Use of this source code is governed by a BSD-style license that can be
3*1a96fba6SXin Li // found in the LICENSE file.
4*1a96fba6SXin Li 
5*1a96fba6SXin Li #include "policy/device_policy_impl.h"
6*1a96fba6SXin Li 
7*1a96fba6SXin Li #include <algorithm>
8*1a96fba6SXin Li #include <map>
9*1a96fba6SXin Li #include <memory>
10*1a96fba6SXin Li #include <set>
11*1a96fba6SXin Li #include <string>
12*1a96fba6SXin Li 
13*1a96fba6SXin Li #include <base/containers/adapters.h>
14*1a96fba6SXin Li #include <base/files/file_util.h>
15*1a96fba6SXin Li #include <base/json/json_reader.h>
16*1a96fba6SXin Li #include <base/logging.h>
17*1a96fba6SXin Li #include <base/macros.h>
18*1a96fba6SXin Li #include <base/memory/ptr_util.h>
19*1a96fba6SXin Li #include <base/stl_util.h>
20*1a96fba6SXin Li #include <base/time/time.h>
21*1a96fba6SXin Li #include <base/values.h>
22*1a96fba6SXin Li #include <openssl/evp.h>
23*1a96fba6SXin Li #include <openssl/x509.h>
24*1a96fba6SXin Li 
25*1a96fba6SXin Li #include "bindings/chrome_device_policy.pb.h"
26*1a96fba6SXin Li #include "bindings/device_management_backend.pb.h"
27*1a96fba6SXin Li #include "policy/policy_util.h"
28*1a96fba6SXin Li #include "policy/resilient_policy_util.h"
29*1a96fba6SXin Li 
30*1a96fba6SXin Li namespace em = enterprise_management;
31*1a96fba6SXin Li 
32*1a96fba6SXin Li namespace policy {
33*1a96fba6SXin Li 
34*1a96fba6SXin Li // TODO(crbug.com/984789): Remove once support for OpenSSL <1.1 is dropped.
35*1a96fba6SXin Li #if OPENSSL_VERSION_NUMBER < 0x10100000L
36*1a96fba6SXin Li #define EVP_MD_CTX_new EVP_MD_CTX_create
37*1a96fba6SXin Li #define EVP_MD_CTX_free EVP_MD_CTX_destroy
38*1a96fba6SXin Li #endif
39*1a96fba6SXin Li 
40*1a96fba6SXin Li // Maximum value of RollbackAllowedMilestones policy.
41*1a96fba6SXin Li const int kMaxRollbackAllowedMilestones = 4;
42*1a96fba6SXin Li 
43*1a96fba6SXin Li namespace {
44*1a96fba6SXin Li const char kPolicyPath[] = "/var/lib/whitelist/policy";
45*1a96fba6SXin Li const char kPublicKeyPath[] = "/var/lib/whitelist/owner.key";
46*1a96fba6SXin Li 
47*1a96fba6SXin Li // Reads the public key used to sign the policy from |key_file| and stores it
48*1a96fba6SXin Li // in |public_key|. Returns true on success.
ReadPublicKeyFromFile(const base::FilePath & key_file,std::string * public_key)49*1a96fba6SXin Li bool ReadPublicKeyFromFile(const base::FilePath& key_file,
50*1a96fba6SXin Li                            std::string* public_key) {
51*1a96fba6SXin Li   if (!base::PathExists(key_file))
52*1a96fba6SXin Li     return false;
53*1a96fba6SXin Li   public_key->clear();
54*1a96fba6SXin Li   if (!base::ReadFileToString(key_file, public_key) || public_key->empty()) {
55*1a96fba6SXin Li     LOG(ERROR) << "Could not read public key off disk";
56*1a96fba6SXin Li     return false;
57*1a96fba6SXin Li   }
58*1a96fba6SXin Li   return true;
59*1a96fba6SXin Li }
60*1a96fba6SXin Li 
61*1a96fba6SXin Li // Verifies that the |signed_data| has correct |signature| with |public_key|.
VerifySignature(const std::string & signed_data,const std::string & signature,const std::string & public_key)62*1a96fba6SXin Li bool VerifySignature(const std::string& signed_data,
63*1a96fba6SXin Li                      const std::string& signature,
64*1a96fba6SXin Li                      const std::string& public_key) {
65*1a96fba6SXin Li   std::unique_ptr<EVP_MD_CTX, void (*)(EVP_MD_CTX *)> ctx(EVP_MD_CTX_new(),
66*1a96fba6SXin Li                                                           EVP_MD_CTX_free);
67*1a96fba6SXin Li   if (!ctx)
68*1a96fba6SXin Li     return false;
69*1a96fba6SXin Li 
70*1a96fba6SXin Li   const EVP_MD* digest = EVP_sha1();
71*1a96fba6SXin Li 
72*1a96fba6SXin Li   char* key = const_cast<char*>(public_key.data());
73*1a96fba6SXin Li   BIO* bio = BIO_new_mem_buf(key, public_key.length());
74*1a96fba6SXin Li   if (!bio)
75*1a96fba6SXin Li     return false;
76*1a96fba6SXin Li 
77*1a96fba6SXin Li   EVP_PKEY* public_key_ssl = d2i_PUBKEY_bio(bio, nullptr);
78*1a96fba6SXin Li   if (!public_key_ssl) {
79*1a96fba6SXin Li     BIO_free_all(bio);
80*1a96fba6SXin Li     return false;
81*1a96fba6SXin Li   }
82*1a96fba6SXin Li 
83*1a96fba6SXin Li   const unsigned char* sig =
84*1a96fba6SXin Li       reinterpret_cast<const unsigned char*>(signature.data());
85*1a96fba6SXin Li   int rv = EVP_VerifyInit_ex(ctx.get(), digest, nullptr);
86*1a96fba6SXin Li   if (rv == 1) {
87*1a96fba6SXin Li     EVP_VerifyUpdate(ctx.get(), signed_data.data(), signed_data.length());
88*1a96fba6SXin Li     rv = EVP_VerifyFinal(ctx.get(), sig, signature.length(), public_key_ssl);
89*1a96fba6SXin Li   }
90*1a96fba6SXin Li 
91*1a96fba6SXin Li   EVP_PKEY_free(public_key_ssl);
92*1a96fba6SXin Li   BIO_free_all(bio);
93*1a96fba6SXin Li 
94*1a96fba6SXin Li   return rv == 1;
95*1a96fba6SXin Li }
96*1a96fba6SXin Li 
97*1a96fba6SXin Li // Decodes the connection type enum from the device settings protobuf to string
98*1a96fba6SXin Li // representations. The strings must match the connection manager definitions.
DecodeConnectionType(int type)99*1a96fba6SXin Li std::string DecodeConnectionType(int type) {
100*1a96fba6SXin Li   static const char* const kConnectionTypes[] = {
101*1a96fba6SXin Li       "ethernet", "wifi", "wimax", "bluetooth", "cellular",
102*1a96fba6SXin Li   };
103*1a96fba6SXin Li 
104*1a96fba6SXin Li   if (type < 0 || type >= static_cast<int>(base::size(kConnectionTypes)))
105*1a96fba6SXin Li     return std::string();
106*1a96fba6SXin Li 
107*1a96fba6SXin Li   return kConnectionTypes[type];
108*1a96fba6SXin Li }
109*1a96fba6SXin Li 
110*1a96fba6SXin Li // TODO(adokar): change type to base::Optional<int> when available.
ConvertDayOfWeekStringToInt(const std::string & day_of_week_str)111*1a96fba6SXin Li int ConvertDayOfWeekStringToInt(const std::string& day_of_week_str) {
112*1a96fba6SXin Li   if (day_of_week_str == "Sunday") return 0;
113*1a96fba6SXin Li   if (day_of_week_str == "Monday") return 1;
114*1a96fba6SXin Li   if (day_of_week_str == "Tuesday") return 2;
115*1a96fba6SXin Li   if (day_of_week_str == "Wednesday") return 3;
116*1a96fba6SXin Li   if (day_of_week_str == "Thursday") return 4;
117*1a96fba6SXin Li   if (day_of_week_str == "Friday") return 5;
118*1a96fba6SXin Li   if (day_of_week_str == "Saturday") return 6;
119*1a96fba6SXin Li   return -1;
120*1a96fba6SXin Li }
121*1a96fba6SXin Li 
DecodeWeeklyTimeFromValue(const base::DictionaryValue & dict_value,int * day_of_week_out,base::TimeDelta * time_out)122*1a96fba6SXin Li bool DecodeWeeklyTimeFromValue(const base::DictionaryValue& dict_value,
123*1a96fba6SXin Li                                int* day_of_week_out,
124*1a96fba6SXin Li                                base::TimeDelta* time_out) {
125*1a96fba6SXin Li   std::string day_of_week_str;
126*1a96fba6SXin Li   if (!dict_value.GetString("day_of_week", &day_of_week_str)) {
127*1a96fba6SXin Li     LOG(ERROR) << "Day of the week is absent.";
128*1a96fba6SXin Li     return false;
129*1a96fba6SXin Li   }
130*1a96fba6SXin Li   *day_of_week_out = ConvertDayOfWeekStringToInt(day_of_week_str);
131*1a96fba6SXin Li   if (*day_of_week_out == -1) {
132*1a96fba6SXin Li     LOG(ERROR) << "Undefined day of the week: " << day_of_week_str;
133*1a96fba6SXin Li     return false;
134*1a96fba6SXin Li   }
135*1a96fba6SXin Li 
136*1a96fba6SXin Li   int hours;
137*1a96fba6SXin Li   if (!dict_value.GetInteger("hours", &hours) || hours < 0 || hours > 23) {
138*1a96fba6SXin Li     LOG(ERROR) << "Hours are absent or are outside of the range [0, 24).";
139*1a96fba6SXin Li     return false;
140*1a96fba6SXin Li   }
141*1a96fba6SXin Li 
142*1a96fba6SXin Li   int minutes;
143*1a96fba6SXin Li   if (!dict_value.GetInteger("minutes", &minutes) || minutes < 0 ||
144*1a96fba6SXin Li       minutes > 59) {
145*1a96fba6SXin Li     LOG(ERROR) << "Minutes are absent or are outside the range [0, 60)";
146*1a96fba6SXin Li     return false;
147*1a96fba6SXin Li   }
148*1a96fba6SXin Li 
149*1a96fba6SXin Li   *time_out =
150*1a96fba6SXin Li       base::TimeDelta::FromMinutes(minutes) + base::TimeDelta::FromHours(hours);
151*1a96fba6SXin Li   return true;
152*1a96fba6SXin Li }
153*1a96fba6SXin Li 
DecodeListValueFromJSON(const std::string & json_string)154*1a96fba6SXin Li std::unique_ptr<base::ListValue> DecodeListValueFromJSON(
155*1a96fba6SXin Li     const std::string& json_string) {
156*1a96fba6SXin Li   std::string error;
157*1a96fba6SXin Li   std::unique_ptr<base::Value> decoded_json =
158*1a96fba6SXin Li       base::JSONReader::ReadAndReturnError(json_string,
159*1a96fba6SXin Li                                            base::JSON_ALLOW_TRAILING_COMMAS,
160*1a96fba6SXin Li                                            nullptr, &error);
161*1a96fba6SXin Li   if (!decoded_json) {
162*1a96fba6SXin Li     LOG(ERROR) << "Invalid JSON string: " << error;
163*1a96fba6SXin Li     return nullptr;
164*1a96fba6SXin Li   }
165*1a96fba6SXin Li 
166*1a96fba6SXin Li   std::unique_ptr<base::ListValue> list_val =
167*1a96fba6SXin Li       base::ListValue::From(std::move(decoded_json));
168*1a96fba6SXin Li   if (!list_val) {
169*1a96fba6SXin Li     LOG(ERROR) << "JSON string is not a list";
170*1a96fba6SXin Li     return nullptr;
171*1a96fba6SXin Li   }
172*1a96fba6SXin Li 
173*1a96fba6SXin Li   return list_val;
174*1a96fba6SXin Li }
175*1a96fba6SXin Li 
176*1a96fba6SXin Li }  // namespace
177*1a96fba6SXin Li 
DevicePolicyImpl()178*1a96fba6SXin Li DevicePolicyImpl::DevicePolicyImpl()
179*1a96fba6SXin Li     : policy_path_(kPolicyPath), keyfile_path_(kPublicKeyPath) {}
180*1a96fba6SXin Li 
~DevicePolicyImpl()181*1a96fba6SXin Li DevicePolicyImpl::~DevicePolicyImpl() {}
182*1a96fba6SXin Li 
LoadPolicy()183*1a96fba6SXin Li bool DevicePolicyImpl::LoadPolicy() {
184*1a96fba6SXin Li   std::map<int, base::FilePath> sorted_policy_file_paths =
185*1a96fba6SXin Li       policy::GetSortedResilientPolicyFilePaths(policy_path_);
186*1a96fba6SXin Li   if (sorted_policy_file_paths.empty())
187*1a96fba6SXin Li     return false;
188*1a96fba6SXin Li 
189*1a96fba6SXin Li   // Try to load the existent policy files one by one in reverse order of their
190*1a96fba6SXin Li   // index until we succeed. The default policy, if present, appears as index 0
191*1a96fba6SXin Li   // in the map and is loaded the last. This is intentional as that file is the
192*1a96fba6SXin Li   // oldest.
193*1a96fba6SXin Li   bool policy_loaded = false;
194*1a96fba6SXin Li   for (const auto& map_pair : base::Reversed(sorted_policy_file_paths)) {
195*1a96fba6SXin Li     const base::FilePath& policy_path = map_pair.second;
196*1a96fba6SXin Li     if (LoadPolicyFromFile(policy_path)) {
197*1a96fba6SXin Li       policy_loaded = true;
198*1a96fba6SXin Li       break;
199*1a96fba6SXin Li     }
200*1a96fba6SXin Li   }
201*1a96fba6SXin Li 
202*1a96fba6SXin Li   return policy_loaded;
203*1a96fba6SXin Li }
204*1a96fba6SXin Li 
IsEnterpriseEnrolled() const205*1a96fba6SXin Li bool DevicePolicyImpl::IsEnterpriseEnrolled() const {
206*1a96fba6SXin Li   DCHECK(install_attributes_reader_);
207*1a96fba6SXin Li   if (!install_attributes_reader_->IsLocked())
208*1a96fba6SXin Li     return false;
209*1a96fba6SXin Li 
210*1a96fba6SXin Li   const std::string& device_mode = install_attributes_reader_->GetAttribute(
211*1a96fba6SXin Li       InstallAttributesReader::kAttrMode);
212*1a96fba6SXin Li   return device_mode == InstallAttributesReader::kDeviceModeEnterprise ||
213*1a96fba6SXin Li       device_mode == InstallAttributesReader::kDeviceModeEnterpriseAD;
214*1a96fba6SXin Li }
215*1a96fba6SXin Li 
GetPolicyRefreshRate(int * rate) const216*1a96fba6SXin Li bool DevicePolicyImpl::GetPolicyRefreshRate(int* rate) const {
217*1a96fba6SXin Li   if (!device_policy_.has_device_policy_refresh_rate())
218*1a96fba6SXin Li     return false;
219*1a96fba6SXin Li   *rate = static_cast<int>(
220*1a96fba6SXin Li       device_policy_.device_policy_refresh_rate().device_policy_refresh_rate());
221*1a96fba6SXin Li   return true;
222*1a96fba6SXin Li }
223*1a96fba6SXin Li 
GetUserWhitelist(std::vector<std::string> * user_whitelist) const224*1a96fba6SXin Li bool DevicePolicyImpl::GetUserWhitelist(
225*1a96fba6SXin Li     std::vector<std::string>* user_whitelist) const {
226*1a96fba6SXin Li   if (!device_policy_.has_user_whitelist())
227*1a96fba6SXin Li     return false;
228*1a96fba6SXin Li   const em::UserWhitelistProto& proto = device_policy_.user_whitelist();
229*1a96fba6SXin Li   user_whitelist->clear();
230*1a96fba6SXin Li   for (int i = 0; i < proto.user_whitelist_size(); i++)
231*1a96fba6SXin Li     user_whitelist->push_back(proto.user_whitelist(i));
232*1a96fba6SXin Li   return true;
233*1a96fba6SXin Li }
234*1a96fba6SXin Li 
GetGuestModeEnabled(bool * guest_mode_enabled) const235*1a96fba6SXin Li bool DevicePolicyImpl::GetGuestModeEnabled(bool* guest_mode_enabled) const {
236*1a96fba6SXin Li   if (!device_policy_.has_guest_mode_enabled())
237*1a96fba6SXin Li     return false;
238*1a96fba6SXin Li   *guest_mode_enabled =
239*1a96fba6SXin Li       device_policy_.guest_mode_enabled().guest_mode_enabled();
240*1a96fba6SXin Li   return true;
241*1a96fba6SXin Li }
242*1a96fba6SXin Li 
GetCameraEnabled(bool * camera_enabled) const243*1a96fba6SXin Li bool DevicePolicyImpl::GetCameraEnabled(bool* camera_enabled) const {
244*1a96fba6SXin Li   if (!device_policy_.has_camera_enabled())
245*1a96fba6SXin Li     return false;
246*1a96fba6SXin Li   *camera_enabled = device_policy_.camera_enabled().camera_enabled();
247*1a96fba6SXin Li   return true;
248*1a96fba6SXin Li }
249*1a96fba6SXin Li 
GetShowUserNames(bool * show_user_names) const250*1a96fba6SXin Li bool DevicePolicyImpl::GetShowUserNames(bool* show_user_names) const {
251*1a96fba6SXin Li   if (!device_policy_.has_show_user_names())
252*1a96fba6SXin Li     return false;
253*1a96fba6SXin Li   *show_user_names = device_policy_.show_user_names().show_user_names();
254*1a96fba6SXin Li   return true;
255*1a96fba6SXin Li }
256*1a96fba6SXin Li 
GetDataRoamingEnabled(bool * data_roaming_enabled) const257*1a96fba6SXin Li bool DevicePolicyImpl::GetDataRoamingEnabled(bool* data_roaming_enabled) const {
258*1a96fba6SXin Li   if (!device_policy_.has_data_roaming_enabled())
259*1a96fba6SXin Li     return false;
260*1a96fba6SXin Li   *data_roaming_enabled =
261*1a96fba6SXin Li       device_policy_.data_roaming_enabled().data_roaming_enabled();
262*1a96fba6SXin Li   return true;
263*1a96fba6SXin Li }
264*1a96fba6SXin Li 
GetAllowNewUsers(bool * allow_new_users) const265*1a96fba6SXin Li bool DevicePolicyImpl::GetAllowNewUsers(bool* allow_new_users) const {
266*1a96fba6SXin Li   if (!device_policy_.has_allow_new_users())
267*1a96fba6SXin Li     return false;
268*1a96fba6SXin Li   *allow_new_users = device_policy_.allow_new_users().allow_new_users();
269*1a96fba6SXin Li   return true;
270*1a96fba6SXin Li }
271*1a96fba6SXin Li 
GetMetricsEnabled(bool * metrics_enabled) const272*1a96fba6SXin Li bool DevicePolicyImpl::GetMetricsEnabled(bool* metrics_enabled) const {
273*1a96fba6SXin Li   if (!device_policy_.has_metrics_enabled())
274*1a96fba6SXin Li     return false;
275*1a96fba6SXin Li   *metrics_enabled = device_policy_.metrics_enabled().metrics_enabled();
276*1a96fba6SXin Li   return true;
277*1a96fba6SXin Li }
278*1a96fba6SXin Li 
GetReportVersionInfo(bool * report_version_info) const279*1a96fba6SXin Li bool DevicePolicyImpl::GetReportVersionInfo(bool* report_version_info) const {
280*1a96fba6SXin Li   if (!device_policy_.has_device_reporting())
281*1a96fba6SXin Li     return false;
282*1a96fba6SXin Li 
283*1a96fba6SXin Li   const em::DeviceReportingProto& proto = device_policy_.device_reporting();
284*1a96fba6SXin Li   if (!proto.has_report_version_info())
285*1a96fba6SXin Li     return false;
286*1a96fba6SXin Li 
287*1a96fba6SXin Li   *report_version_info = proto.report_version_info();
288*1a96fba6SXin Li   return true;
289*1a96fba6SXin Li }
290*1a96fba6SXin Li 
GetReportActivityTimes(bool * report_activity_times) const291*1a96fba6SXin Li bool DevicePolicyImpl::GetReportActivityTimes(
292*1a96fba6SXin Li     bool* report_activity_times) const {
293*1a96fba6SXin Li   if (!device_policy_.has_device_reporting())
294*1a96fba6SXin Li     return false;
295*1a96fba6SXin Li 
296*1a96fba6SXin Li   const em::DeviceReportingProto& proto = device_policy_.device_reporting();
297*1a96fba6SXin Li   if (!proto.has_report_activity_times())
298*1a96fba6SXin Li     return false;
299*1a96fba6SXin Li 
300*1a96fba6SXin Li   *report_activity_times = proto.report_activity_times();
301*1a96fba6SXin Li   return true;
302*1a96fba6SXin Li }
303*1a96fba6SXin Li 
GetReportBootMode(bool * report_boot_mode) const304*1a96fba6SXin Li bool DevicePolicyImpl::GetReportBootMode(bool* report_boot_mode) const {
305*1a96fba6SXin Li   if (!device_policy_.has_device_reporting())
306*1a96fba6SXin Li     return false;
307*1a96fba6SXin Li 
308*1a96fba6SXin Li   const em::DeviceReportingProto& proto = device_policy_.device_reporting();
309*1a96fba6SXin Li   if (!proto.has_report_boot_mode())
310*1a96fba6SXin Li     return false;
311*1a96fba6SXin Li 
312*1a96fba6SXin Li   *report_boot_mode = proto.report_boot_mode();
313*1a96fba6SXin Li   return true;
314*1a96fba6SXin Li }
315*1a96fba6SXin Li 
GetEphemeralUsersEnabled(bool * ephemeral_users_enabled) const316*1a96fba6SXin Li bool DevicePolicyImpl::GetEphemeralUsersEnabled(
317*1a96fba6SXin Li     bool* ephemeral_users_enabled) const {
318*1a96fba6SXin Li   if (!device_policy_.has_ephemeral_users_enabled())
319*1a96fba6SXin Li     return false;
320*1a96fba6SXin Li   *ephemeral_users_enabled =
321*1a96fba6SXin Li       device_policy_.ephemeral_users_enabled().ephemeral_users_enabled();
322*1a96fba6SXin Li   return true;
323*1a96fba6SXin Li }
324*1a96fba6SXin Li 
GetReleaseChannel(std::string * release_channel) const325*1a96fba6SXin Li bool DevicePolicyImpl::GetReleaseChannel(std::string* release_channel) const {
326*1a96fba6SXin Li   if (!device_policy_.has_release_channel())
327*1a96fba6SXin Li     return false;
328*1a96fba6SXin Li 
329*1a96fba6SXin Li   const em::ReleaseChannelProto& proto = device_policy_.release_channel();
330*1a96fba6SXin Li   if (!proto.has_release_channel())
331*1a96fba6SXin Li     return false;
332*1a96fba6SXin Li 
333*1a96fba6SXin Li   *release_channel = proto.release_channel();
334*1a96fba6SXin Li   return true;
335*1a96fba6SXin Li }
336*1a96fba6SXin Li 
GetReleaseChannelDelegated(bool * release_channel_delegated) const337*1a96fba6SXin Li bool DevicePolicyImpl::GetReleaseChannelDelegated(
338*1a96fba6SXin Li     bool* release_channel_delegated) const {
339*1a96fba6SXin Li   if (!device_policy_.has_release_channel())
340*1a96fba6SXin Li     return false;
341*1a96fba6SXin Li 
342*1a96fba6SXin Li   const em::ReleaseChannelProto& proto = device_policy_.release_channel();
343*1a96fba6SXin Li   if (!proto.has_release_channel_delegated())
344*1a96fba6SXin Li     return false;
345*1a96fba6SXin Li 
346*1a96fba6SXin Li   *release_channel_delegated = proto.release_channel_delegated();
347*1a96fba6SXin Li   return true;
348*1a96fba6SXin Li }
349*1a96fba6SXin Li 
GetUpdateDisabled(bool * update_disabled) const350*1a96fba6SXin Li bool DevicePolicyImpl::GetUpdateDisabled(bool* update_disabled) const {
351*1a96fba6SXin Li   if (!IsEnterpriseEnrolled())
352*1a96fba6SXin Li     return false;
353*1a96fba6SXin Li 
354*1a96fba6SXin Li   if (!device_policy_.has_auto_update_settings())
355*1a96fba6SXin Li     return false;
356*1a96fba6SXin Li 
357*1a96fba6SXin Li   const em::AutoUpdateSettingsProto& proto =
358*1a96fba6SXin Li       device_policy_.auto_update_settings();
359*1a96fba6SXin Li   if (!proto.has_update_disabled())
360*1a96fba6SXin Li     return false;
361*1a96fba6SXin Li 
362*1a96fba6SXin Li   *update_disabled = proto.update_disabled();
363*1a96fba6SXin Li   return true;
364*1a96fba6SXin Li }
365*1a96fba6SXin Li 
GetTargetVersionPrefix(std::string * target_version_prefix) const366*1a96fba6SXin Li bool DevicePolicyImpl::GetTargetVersionPrefix(
367*1a96fba6SXin Li     std::string* target_version_prefix) const {
368*1a96fba6SXin Li   if (!IsEnterpriseEnrolled())
369*1a96fba6SXin Li     return false;
370*1a96fba6SXin Li 
371*1a96fba6SXin Li   if (!device_policy_.has_auto_update_settings())
372*1a96fba6SXin Li     return false;
373*1a96fba6SXin Li 
374*1a96fba6SXin Li   const em::AutoUpdateSettingsProto& proto =
375*1a96fba6SXin Li       device_policy_.auto_update_settings();
376*1a96fba6SXin Li   if (!proto.has_target_version_prefix())
377*1a96fba6SXin Li     return false;
378*1a96fba6SXin Li 
379*1a96fba6SXin Li   *target_version_prefix = proto.target_version_prefix();
380*1a96fba6SXin Li   return true;
381*1a96fba6SXin Li }
382*1a96fba6SXin Li 
GetRollbackToTargetVersion(int * rollback_to_target_version) const383*1a96fba6SXin Li bool DevicePolicyImpl::GetRollbackToTargetVersion(
384*1a96fba6SXin Li     int* rollback_to_target_version) const {
385*1a96fba6SXin Li   if (!device_policy_.has_auto_update_settings())
386*1a96fba6SXin Li     return false;
387*1a96fba6SXin Li 
388*1a96fba6SXin Li   const em::AutoUpdateSettingsProto& proto =
389*1a96fba6SXin Li       device_policy_.auto_update_settings();
390*1a96fba6SXin Li   if (!proto.has_rollback_to_target_version())
391*1a96fba6SXin Li     return false;
392*1a96fba6SXin Li 
393*1a96fba6SXin Li   *rollback_to_target_version = proto.rollback_to_target_version();
394*1a96fba6SXin Li   return true;
395*1a96fba6SXin Li }
396*1a96fba6SXin Li 
GetRollbackAllowedMilestones(int * rollback_allowed_milestones) const397*1a96fba6SXin Li bool DevicePolicyImpl::GetRollbackAllowedMilestones(
398*1a96fba6SXin Li     int* rollback_allowed_milestones) const {
399*1a96fba6SXin Li   // This policy can be only set for devices which are enterprise enrolled.
400*1a96fba6SXin Li   if (!IsEnterpriseEnrolled())
401*1a96fba6SXin Li     return false;
402*1a96fba6SXin Li 
403*1a96fba6SXin Li   if (device_policy_.has_auto_update_settings()) {
404*1a96fba6SXin Li     const em::AutoUpdateSettingsProto& proto =
405*1a96fba6SXin Li         device_policy_.auto_update_settings();
406*1a96fba6SXin Li     if (proto.has_rollback_allowed_milestones()) {
407*1a96fba6SXin Li       // Policy is set, enforce minimum and maximum constraints.
408*1a96fba6SXin Li       *rollback_allowed_milestones = proto.rollback_allowed_milestones();
409*1a96fba6SXin Li       if (*rollback_allowed_milestones < 0)
410*1a96fba6SXin Li         *rollback_allowed_milestones = 0;
411*1a96fba6SXin Li       if (*rollback_allowed_milestones > kMaxRollbackAllowedMilestones)
412*1a96fba6SXin Li         *rollback_allowed_milestones = kMaxRollbackAllowedMilestones;
413*1a96fba6SXin Li       return true;
414*1a96fba6SXin Li     }
415*1a96fba6SXin Li   }
416*1a96fba6SXin Li   // Policy is not present, use default for enterprise devices.
417*1a96fba6SXin Li   VLOG(1) << "RollbackAllowedMilestones policy is not set, using default "
418*1a96fba6SXin Li           << kMaxRollbackAllowedMilestones << ".";
419*1a96fba6SXin Li   *rollback_allowed_milestones = kMaxRollbackAllowedMilestones;
420*1a96fba6SXin Li   return true;
421*1a96fba6SXin Li }
422*1a96fba6SXin Li 
GetScatterFactorInSeconds(int64_t * scatter_factor_in_seconds) const423*1a96fba6SXin Li bool DevicePolicyImpl::GetScatterFactorInSeconds(
424*1a96fba6SXin Li     int64_t* scatter_factor_in_seconds) const {
425*1a96fba6SXin Li   if (!device_policy_.has_auto_update_settings())
426*1a96fba6SXin Li     return false;
427*1a96fba6SXin Li 
428*1a96fba6SXin Li   const em::AutoUpdateSettingsProto& proto =
429*1a96fba6SXin Li       device_policy_.auto_update_settings();
430*1a96fba6SXin Li   if (!proto.has_scatter_factor_in_seconds())
431*1a96fba6SXin Li     return false;
432*1a96fba6SXin Li 
433*1a96fba6SXin Li   *scatter_factor_in_seconds = proto.scatter_factor_in_seconds();
434*1a96fba6SXin Li   return true;
435*1a96fba6SXin Li }
436*1a96fba6SXin Li 
GetAllowedConnectionTypesForUpdate(std::set<std::string> * connection_types) const437*1a96fba6SXin Li bool DevicePolicyImpl::GetAllowedConnectionTypesForUpdate(
438*1a96fba6SXin Li     std::set<std::string>* connection_types) const {
439*1a96fba6SXin Li   if (!IsEnterpriseEnrolled())
440*1a96fba6SXin Li     return false;
441*1a96fba6SXin Li 
442*1a96fba6SXin Li   if (!device_policy_.has_auto_update_settings())
443*1a96fba6SXin Li     return false;
444*1a96fba6SXin Li 
445*1a96fba6SXin Li   const em::AutoUpdateSettingsProto& proto =
446*1a96fba6SXin Li       device_policy_.auto_update_settings();
447*1a96fba6SXin Li   if (proto.allowed_connection_types_size() <= 0)
448*1a96fba6SXin Li     return false;
449*1a96fba6SXin Li 
450*1a96fba6SXin Li   for (int i = 0; i < proto.allowed_connection_types_size(); i++) {
451*1a96fba6SXin Li     std::string type = DecodeConnectionType(proto.allowed_connection_types(i));
452*1a96fba6SXin Li     if (!type.empty())
453*1a96fba6SXin Li       connection_types->insert(type);
454*1a96fba6SXin Li   }
455*1a96fba6SXin Li   return true;
456*1a96fba6SXin Li }
457*1a96fba6SXin Li 
GetOpenNetworkConfiguration(std::string * open_network_configuration) const458*1a96fba6SXin Li bool DevicePolicyImpl::GetOpenNetworkConfiguration(
459*1a96fba6SXin Li     std::string* open_network_configuration) const {
460*1a96fba6SXin Li   if (!device_policy_.has_open_network_configuration())
461*1a96fba6SXin Li     return false;
462*1a96fba6SXin Li 
463*1a96fba6SXin Li   const em::DeviceOpenNetworkConfigurationProto& proto =
464*1a96fba6SXin Li       device_policy_.open_network_configuration();
465*1a96fba6SXin Li   if (!proto.has_open_network_configuration())
466*1a96fba6SXin Li     return false;
467*1a96fba6SXin Li 
468*1a96fba6SXin Li   *open_network_configuration = proto.open_network_configuration();
469*1a96fba6SXin Li   return true;
470*1a96fba6SXin Li }
471*1a96fba6SXin Li 
GetOwner(std::string * owner) const472*1a96fba6SXin Li bool DevicePolicyImpl::GetOwner(std::string* owner) const {
473*1a96fba6SXin Li   if (IsEnterpriseManaged()) {
474*1a96fba6SXin Li     *owner = "";
475*1a96fba6SXin Li     return true;
476*1a96fba6SXin Li   }
477*1a96fba6SXin Li 
478*1a96fba6SXin Li   if (!policy_data_.has_username())
479*1a96fba6SXin Li     return false;
480*1a96fba6SXin Li   *owner = policy_data_.username();
481*1a96fba6SXin Li   return true;
482*1a96fba6SXin Li }
483*1a96fba6SXin Li 
GetHttpDownloadsEnabled(bool * http_downloads_enabled) const484*1a96fba6SXin Li bool DevicePolicyImpl::GetHttpDownloadsEnabled(
485*1a96fba6SXin Li     bool* http_downloads_enabled) const {
486*1a96fba6SXin Li   if (!device_policy_.has_auto_update_settings())
487*1a96fba6SXin Li     return false;
488*1a96fba6SXin Li 
489*1a96fba6SXin Li   const em::AutoUpdateSettingsProto& proto =
490*1a96fba6SXin Li       device_policy_.auto_update_settings();
491*1a96fba6SXin Li 
492*1a96fba6SXin Li   if (!proto.has_http_downloads_enabled())
493*1a96fba6SXin Li     return false;
494*1a96fba6SXin Li 
495*1a96fba6SXin Li   *http_downloads_enabled = proto.http_downloads_enabled();
496*1a96fba6SXin Li   return true;
497*1a96fba6SXin Li }
498*1a96fba6SXin Li 
GetAuP2PEnabled(bool * au_p2p_enabled) const499*1a96fba6SXin Li bool DevicePolicyImpl::GetAuP2PEnabled(bool* au_p2p_enabled) const {
500*1a96fba6SXin Li   if (!device_policy_.has_auto_update_settings())
501*1a96fba6SXin Li     return false;
502*1a96fba6SXin Li 
503*1a96fba6SXin Li   const em::AutoUpdateSettingsProto& proto =
504*1a96fba6SXin Li       device_policy_.auto_update_settings();
505*1a96fba6SXin Li 
506*1a96fba6SXin Li   if (!proto.has_p2p_enabled())
507*1a96fba6SXin Li     return false;
508*1a96fba6SXin Li 
509*1a96fba6SXin Li   *au_p2p_enabled = proto.p2p_enabled();
510*1a96fba6SXin Li   return true;
511*1a96fba6SXin Li }
512*1a96fba6SXin Li 
GetAllowKioskAppControlChromeVersion(bool * allow_kiosk_app_control_chrome_version) const513*1a96fba6SXin Li bool DevicePolicyImpl::GetAllowKioskAppControlChromeVersion(
514*1a96fba6SXin Li     bool* allow_kiosk_app_control_chrome_version) const {
515*1a96fba6SXin Li   if (!device_policy_.has_allow_kiosk_app_control_chrome_version())
516*1a96fba6SXin Li     return false;
517*1a96fba6SXin Li 
518*1a96fba6SXin Li   const em::AllowKioskAppControlChromeVersionProto& proto =
519*1a96fba6SXin Li       device_policy_.allow_kiosk_app_control_chrome_version();
520*1a96fba6SXin Li 
521*1a96fba6SXin Li   if (!proto.has_allow_kiosk_app_control_chrome_version())
522*1a96fba6SXin Li     return false;
523*1a96fba6SXin Li 
524*1a96fba6SXin Li   *allow_kiosk_app_control_chrome_version =
525*1a96fba6SXin Li       proto.allow_kiosk_app_control_chrome_version();
526*1a96fba6SXin Li   return true;
527*1a96fba6SXin Li }
528*1a96fba6SXin Li 
GetUsbDetachableWhitelist(std::vector<UsbDeviceId> * usb_whitelist) const529*1a96fba6SXin Li bool DevicePolicyImpl::GetUsbDetachableWhitelist(
530*1a96fba6SXin Li     std::vector<UsbDeviceId>* usb_whitelist) const {
531*1a96fba6SXin Li   if (!device_policy_.has_usb_detachable_whitelist())
532*1a96fba6SXin Li     return false;
533*1a96fba6SXin Li   const em::UsbDetachableWhitelistProto& proto =
534*1a96fba6SXin Li       device_policy_.usb_detachable_whitelist();
535*1a96fba6SXin Li   usb_whitelist->clear();
536*1a96fba6SXin Li   for (int i = 0; i < proto.id_size(); i++) {
537*1a96fba6SXin Li     const em::UsbDeviceIdProto& id = proto.id(i);
538*1a96fba6SXin Li     UsbDeviceId dev_id;
539*1a96fba6SXin Li     dev_id.vendor_id = id.has_vendor_id() ? id.vendor_id() : 0;
540*1a96fba6SXin Li     dev_id.product_id = id.has_product_id() ? id.product_id() : 0;
541*1a96fba6SXin Li     usb_whitelist->push_back(dev_id);
542*1a96fba6SXin Li   }
543*1a96fba6SXin Li   return true;
544*1a96fba6SXin Li }
545*1a96fba6SXin Li 
GetDeviceUpdateStagingSchedule(std::vector<DayPercentagePair> * staging_schedule_out) const546*1a96fba6SXin Li bool DevicePolicyImpl::GetDeviceUpdateStagingSchedule(
547*1a96fba6SXin Li     std::vector<DayPercentagePair>* staging_schedule_out) const {
548*1a96fba6SXin Li   staging_schedule_out->clear();
549*1a96fba6SXin Li 
550*1a96fba6SXin Li   if (!device_policy_.has_auto_update_settings())
551*1a96fba6SXin Li     return false;
552*1a96fba6SXin Li 
553*1a96fba6SXin Li   const em::AutoUpdateSettingsProto &proto =
554*1a96fba6SXin Li       device_policy_.auto_update_settings();
555*1a96fba6SXin Li 
556*1a96fba6SXin Li   if (!proto.has_staging_schedule())
557*1a96fba6SXin Li     return false;
558*1a96fba6SXin Li 
559*1a96fba6SXin Li   std::unique_ptr<base::ListValue> list_val =
560*1a96fba6SXin Li       DecodeListValueFromJSON(proto.staging_schedule());
561*1a96fba6SXin Li   if (!list_val)
562*1a96fba6SXin Li     return false;
563*1a96fba6SXin Li 
564*1a96fba6SXin Li   for (const auto& pair_value : *list_val) {
565*1a96fba6SXin Li     const base::DictionaryValue* day_percentage_pair;
566*1a96fba6SXin Li     if (!pair_value.GetAsDictionary(&day_percentage_pair))
567*1a96fba6SXin Li       return false;
568*1a96fba6SXin Li     int days, percentage;
569*1a96fba6SXin Li     if (!day_percentage_pair->GetInteger("days", &days) ||
570*1a96fba6SXin Li         !day_percentage_pair->GetInteger("percentage", &percentage))
571*1a96fba6SXin Li       return false;
572*1a96fba6SXin Li     // Limit the percentage to [0, 100] and days to [1, 28];
573*1a96fba6SXin Li     staging_schedule_out->push_back({std::max(std::min(days, 28), 1),
574*1a96fba6SXin Li                                      std::max(std::min(percentage, 100), 0)});
575*1a96fba6SXin Li   }
576*1a96fba6SXin Li 
577*1a96fba6SXin Li   return true;
578*1a96fba6SXin Li }
579*1a96fba6SXin Li 
GetAutoLaunchedKioskAppId(std::string * app_id_out) const580*1a96fba6SXin Li bool DevicePolicyImpl::GetAutoLaunchedKioskAppId(
581*1a96fba6SXin Li     std::string* app_id_out) const {
582*1a96fba6SXin Li   if (!device_policy_.has_device_local_accounts())
583*1a96fba6SXin Li     return false;
584*1a96fba6SXin Li 
585*1a96fba6SXin Li   const em::DeviceLocalAccountsProto& local_accounts =
586*1a96fba6SXin Li       device_policy_.device_local_accounts();
587*1a96fba6SXin Li 
588*1a96fba6SXin Li   // For auto-launched kiosk apps, the delay needs to be 0.
589*1a96fba6SXin Li   if (local_accounts.has_auto_login_delay() &&
590*1a96fba6SXin Li       local_accounts.auto_login_delay() != 0)
591*1a96fba6SXin Li     return false;
592*1a96fba6SXin Li 
593*1a96fba6SXin Li   for (const em::DeviceLocalAccountInfoProto& account :
594*1a96fba6SXin Li        local_accounts.account()) {
595*1a96fba6SXin Li     // If this isn't an auto-login account, move to the next one.
596*1a96fba6SXin Li     if (account.account_id() != local_accounts.auto_login_id())
597*1a96fba6SXin Li       continue;
598*1a96fba6SXin Li 
599*1a96fba6SXin Li     // If the auto-launched account is not a kiosk app, bail out, we aren't
600*1a96fba6SXin Li     // running in auto-launched kiosk mode.
601*1a96fba6SXin Li     if (account.type() !=
602*1a96fba6SXin Li         em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_KIOSK_APP) {
603*1a96fba6SXin Li       return false;
604*1a96fba6SXin Li     }
605*1a96fba6SXin Li 
606*1a96fba6SXin Li     *app_id_out = account.kiosk_app().app_id();
607*1a96fba6SXin Li     return true;
608*1a96fba6SXin Li   }
609*1a96fba6SXin Li 
610*1a96fba6SXin Li   // No auto-launched account found.
611*1a96fba6SXin Li   return false;
612*1a96fba6SXin Li }
613*1a96fba6SXin Li 
IsEnterpriseManaged() const614*1a96fba6SXin Li bool DevicePolicyImpl::IsEnterpriseManaged() const {
615*1a96fba6SXin Li   if (policy_data_.has_management_mode())
616*1a96fba6SXin Li     return policy_data_.management_mode() == em::PolicyData::ENTERPRISE_MANAGED;
617*1a96fba6SXin Li   // Fall back to checking the request token, see management_mode documentation
618*1a96fba6SXin Li   // in device_management_backend.proto.
619*1a96fba6SXin Li   return policy_data_.has_request_token();
620*1a96fba6SXin Li }
621*1a96fba6SXin Li 
GetSecondFactorAuthenticationMode(int * mode_out) const622*1a96fba6SXin Li bool DevicePolicyImpl::GetSecondFactorAuthenticationMode(int* mode_out) const {
623*1a96fba6SXin Li   if (!device_policy_.has_device_second_factor_authentication())
624*1a96fba6SXin Li     return false;
625*1a96fba6SXin Li 
626*1a96fba6SXin Li   const em::DeviceSecondFactorAuthenticationProto& proto =
627*1a96fba6SXin Li       device_policy_.device_second_factor_authentication();
628*1a96fba6SXin Li 
629*1a96fba6SXin Li   if (!proto.has_mode())
630*1a96fba6SXin Li     return false;
631*1a96fba6SXin Li 
632*1a96fba6SXin Li   *mode_out = proto.mode();
633*1a96fba6SXin Li   return true;
634*1a96fba6SXin Li }
635*1a96fba6SXin Li 
GetDisallowedTimeIntervals(std::vector<WeeklyTimeInterval> * intervals_out) const636*1a96fba6SXin Li bool DevicePolicyImpl::GetDisallowedTimeIntervals(
637*1a96fba6SXin Li     std::vector<WeeklyTimeInterval>* intervals_out) const {
638*1a96fba6SXin Li   intervals_out->clear();
639*1a96fba6SXin Li   if (!IsEnterpriseEnrolled())
640*1a96fba6SXin Li     return false;
641*1a96fba6SXin Li 
642*1a96fba6SXin Li   if (!device_policy_.has_auto_update_settings()) {
643*1a96fba6SXin Li     return false;
644*1a96fba6SXin Li   }
645*1a96fba6SXin Li 
646*1a96fba6SXin Li   const em::AutoUpdateSettingsProto& proto =
647*1a96fba6SXin Li       device_policy_.auto_update_settings();
648*1a96fba6SXin Li 
649*1a96fba6SXin Li   if (!proto.has_disallowed_time_intervals()) {
650*1a96fba6SXin Li     return false;
651*1a96fba6SXin Li   }
652*1a96fba6SXin Li 
653*1a96fba6SXin Li   std::unique_ptr<base::ListValue> list_val =
654*1a96fba6SXin Li       DecodeListValueFromJSON(proto.disallowed_time_intervals());
655*1a96fba6SXin Li   if (!list_val)
656*1a96fba6SXin Li     return false;
657*1a96fba6SXin Li 
658*1a96fba6SXin Li   for (const auto& interval_value : *list_val) {
659*1a96fba6SXin Li     const base::DictionaryValue* interval_dict;
660*1a96fba6SXin Li     if (!interval_value.GetAsDictionary(&interval_dict)) {
661*1a96fba6SXin Li       LOG(ERROR) << "Invalid JSON string given. Interval is not a dict.";
662*1a96fba6SXin Li       return false;
663*1a96fba6SXin Li     }
664*1a96fba6SXin Li     const base::DictionaryValue* start;
665*1a96fba6SXin Li     const base::DictionaryValue* end;
666*1a96fba6SXin Li     if (!interval_dict->GetDictionary("start", &start) ||
667*1a96fba6SXin Li         !interval_dict->GetDictionary("end", &end)) {
668*1a96fba6SXin Li       LOG(ERROR) << "Interval is missing start/end.";
669*1a96fba6SXin Li       return false;
670*1a96fba6SXin Li     }
671*1a96fba6SXin Li     WeeklyTimeInterval weekly_interval;
672*1a96fba6SXin Li     if (!DecodeWeeklyTimeFromValue(*start, &weekly_interval.start_day_of_week,
673*1a96fba6SXin Li                                    &weekly_interval.start_time) ||
674*1a96fba6SXin Li         !DecodeWeeklyTimeFromValue(*end, &weekly_interval.end_day_of_week,
675*1a96fba6SXin Li                                    &weekly_interval.end_time)) {
676*1a96fba6SXin Li       return false;
677*1a96fba6SXin Li     }
678*1a96fba6SXin Li 
679*1a96fba6SXin Li     intervals_out->push_back(weekly_interval);
680*1a96fba6SXin Li   }
681*1a96fba6SXin Li   return true;
682*1a96fba6SXin Li }
683*1a96fba6SXin Li 
GetDeviceQuickFixBuildToken(std::string * device_quick_fix_build_token) const684*1a96fba6SXin Li bool DevicePolicyImpl::GetDeviceQuickFixBuildToken(
685*1a96fba6SXin Li     std::string* device_quick_fix_build_token) const {
686*1a96fba6SXin Li   if (!IsEnterpriseEnrolled() || !device_policy_.has_auto_update_settings())
687*1a96fba6SXin Li     return false;
688*1a96fba6SXin Li 
689*1a96fba6SXin Li   const em::AutoUpdateSettingsProto& proto =
690*1a96fba6SXin Li       device_policy_.auto_update_settings();
691*1a96fba6SXin Li   if (!proto.has_device_quick_fix_build_token())
692*1a96fba6SXin Li     return false;
693*1a96fba6SXin Li 
694*1a96fba6SXin Li   *device_quick_fix_build_token = proto.device_quick_fix_build_token();
695*1a96fba6SXin Li   return true;
696*1a96fba6SXin Li }
697*1a96fba6SXin Li 
GetDeviceDirectoryApiId(std::string * directory_api_id_out) const698*1a96fba6SXin Li bool DevicePolicyImpl::GetDeviceDirectoryApiId(
699*1a96fba6SXin Li     std::string* directory_api_id_out) const {
700*1a96fba6SXin Li   if (!policy_data_.has_directory_api_id())
701*1a96fba6SXin Li     return false;
702*1a96fba6SXin Li 
703*1a96fba6SXin Li   *directory_api_id_out = policy_data_.directory_api_id();
704*1a96fba6SXin Li   return true;
705*1a96fba6SXin Li }
706*1a96fba6SXin Li 
VerifyPolicyFile(const base::FilePath & policy_path)707*1a96fba6SXin Li bool DevicePolicyImpl::VerifyPolicyFile(const base::FilePath& policy_path) {
708*1a96fba6SXin Li   if (!verify_root_ownership_) {
709*1a96fba6SXin Li     return true;
710*1a96fba6SXin Li   }
711*1a96fba6SXin Li 
712*1a96fba6SXin Li   // Both the policy and its signature have to exist.
713*1a96fba6SXin Li   if (!base::PathExists(policy_path) || !base::PathExists(keyfile_path_)) {
714*1a96fba6SXin Li     return false;
715*1a96fba6SXin Li   }
716*1a96fba6SXin Li 
717*1a96fba6SXin Li   // Check if the policy and signature file is owned by root.
718*1a96fba6SXin Li   struct stat file_stat;
719*1a96fba6SXin Li   stat(policy_path.value().c_str(), &file_stat);
720*1a96fba6SXin Li   if (file_stat.st_uid != 0) {
721*1a96fba6SXin Li     LOG(ERROR) << "Policy file is not owned by root!";
722*1a96fba6SXin Li     return false;
723*1a96fba6SXin Li   }
724*1a96fba6SXin Li   stat(keyfile_path_.value().c_str(), &file_stat);
725*1a96fba6SXin Li   if (file_stat.st_uid != 0) {
726*1a96fba6SXin Li     LOG(ERROR) << "Policy signature file is not owned by root!";
727*1a96fba6SXin Li     return false;
728*1a96fba6SXin Li   }
729*1a96fba6SXin Li   return true;
730*1a96fba6SXin Li }
731*1a96fba6SXin Li 
VerifyPolicySignature()732*1a96fba6SXin Li bool DevicePolicyImpl::VerifyPolicySignature() {
733*1a96fba6SXin Li   if (policy_.has_policy_data_signature()) {
734*1a96fba6SXin Li     std::string policy_data = policy_.policy_data();
735*1a96fba6SXin Li     std::string policy_data_signature = policy_.policy_data_signature();
736*1a96fba6SXin Li     std::string public_key;
737*1a96fba6SXin Li     if (!ReadPublicKeyFromFile(base::FilePath(keyfile_path_), &public_key)) {
738*1a96fba6SXin Li       LOG(ERROR) << "Could not read owner key off disk";
739*1a96fba6SXin Li       return false;
740*1a96fba6SXin Li     }
741*1a96fba6SXin Li     if (!VerifySignature(policy_data, policy_data_signature, public_key)) {
742*1a96fba6SXin Li       LOG(ERROR) << "Signature does not match the data or can not be verified!";
743*1a96fba6SXin Li       return false;
744*1a96fba6SXin Li     }
745*1a96fba6SXin Li     return true;
746*1a96fba6SXin Li   }
747*1a96fba6SXin Li   LOG(ERROR) << "The policy blob is not signed!";
748*1a96fba6SXin Li   return false;
749*1a96fba6SXin Li }
750*1a96fba6SXin Li 
LoadPolicyFromFile(const base::FilePath & policy_path)751*1a96fba6SXin Li bool DevicePolicyImpl::LoadPolicyFromFile(const base::FilePath& policy_path) {
752*1a96fba6SXin Li   std::string policy_data_str;
753*1a96fba6SXin Li   if (policy::LoadPolicyFromPath(policy_path, &policy_data_str, &policy_) !=
754*1a96fba6SXin Li       LoadPolicyResult::kSuccess) {
755*1a96fba6SXin Li     return false;
756*1a96fba6SXin Li   }
757*1a96fba6SXin Li   if (!policy_.has_policy_data()) {
758*1a96fba6SXin Li     LOG(ERROR) << "Policy on disk could not be parsed!";
759*1a96fba6SXin Li     return false;
760*1a96fba6SXin Li   }
761*1a96fba6SXin Li   if (!policy_data_.ParseFromString(policy_.policy_data()) ||
762*1a96fba6SXin Li       !policy_data_.has_policy_value()) {
763*1a96fba6SXin Li     LOG(ERROR) << "Policy on disk could not be parsed!";
764*1a96fba6SXin Li     return false;
765*1a96fba6SXin Li   }
766*1a96fba6SXin Li 
767*1a96fba6SXin Li   bool verify_policy = verify_policy_;
768*1a96fba6SXin Li   if (!install_attributes_reader_) {
769*1a96fba6SXin Li     install_attributes_reader_ = std::make_unique<InstallAttributesReader>();
770*1a96fba6SXin Li   }
771*1a96fba6SXin Li   const std::string& mode = install_attributes_reader_->GetAttribute(
772*1a96fba6SXin Li       InstallAttributesReader::kAttrMode);
773*1a96fba6SXin Li   if (mode == InstallAttributesReader::kDeviceModeEnterpriseAD) {
774*1a96fba6SXin Li     verify_policy = false;
775*1a96fba6SXin Li   }
776*1a96fba6SXin Li   if (verify_policy && !VerifyPolicyFile(policy_path)) {
777*1a96fba6SXin Li     return false;
778*1a96fba6SXin Li   }
779*1a96fba6SXin Li 
780*1a96fba6SXin Li   // Make sure the signature is still valid.
781*1a96fba6SXin Li   if (verify_policy && !VerifyPolicySignature()) {
782*1a96fba6SXin Li     LOG(ERROR) << "Policy signature verification failed!";
783*1a96fba6SXin Li     return false;
784*1a96fba6SXin Li   }
785*1a96fba6SXin Li   if (!device_policy_.ParseFromString(policy_data_.policy_value())) {
786*1a96fba6SXin Li     LOG(ERROR) << "Policy on disk could not be parsed!";
787*1a96fba6SXin Li     return false;
788*1a96fba6SXin Li   }
789*1a96fba6SXin Li 
790*1a96fba6SXin Li   return true;
791*1a96fba6SXin Li }
792*1a96fba6SXin Li 
793*1a96fba6SXin Li }  // namespace policy
794