1 //
2 // Copyright (C) 2014 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "update_engine/update_manager/real_device_policy_provider.h"
18 
19 #include <stdint.h>
20 
21 #include <vector>
22 
23 #include <base/location.h>
24 #include <base/logging.h>
25 #include <base/time/time.h>
26 #include <policy/device_policy.h>
27 
28 #include "update_engine/common/utils.h"
29 #include "update_engine/connection_utils.h"
30 #include "update_engine/update_manager/generic_variables.h"
31 
32 using base::TimeDelta;
33 using brillo::MessageLoop;
34 using chromeos_update_engine::ConnectionType;
35 using policy::DevicePolicy;
36 using std::set;
37 using std::string;
38 using std::vector;
39 
40 namespace {
41 
42 const int kDevicePolicyRefreshRateInMinutes = 60;
43 
44 }  // namespace
45 
46 namespace chromeos_update_manager {
47 
48 RealDevicePolicyProvider::~RealDevicePolicyProvider() {
49   MessageLoop::current()->CancelTask(scheduled_refresh_);
50 }
51 
52 bool RealDevicePolicyProvider::Init() {
53   CHECK(policy_provider_ != nullptr);
54 
55   // On Init() we try to get the device policy and keep updating it.
56   RefreshDevicePolicyAndReschedule();
57 
58 #if USE_DBUS
59   // We also listen for signals from the session manager to force a device
60   // policy refresh.
61   session_manager_proxy_->RegisterPropertyChangeCompleteSignalHandler(
62       base::Bind(&RealDevicePolicyProvider::OnPropertyChangedCompletedSignal,
63                  base::Unretained(this)),
64       base::Bind(&RealDevicePolicyProvider::OnSignalConnected,
65                  base::Unretained(this)));
66 #endif  // USE_DBUS
67   return true;
68 }
69 
70 void RealDevicePolicyProvider::OnPropertyChangedCompletedSignal(
71     const string& success) {
72   if (success != "success") {
73     LOG(WARNING) << "Received device policy updated signal with a failure.";
74   }
75   // We refresh the policy file even if the payload string is kSignalFailure.
76   LOG(INFO) << "Reloading and re-scheduling device policy due to signal "
77                "received.";
78   MessageLoop::current()->CancelTask(scheduled_refresh_);
79   scheduled_refresh_ = MessageLoop::kTaskIdNull;
80   RefreshDevicePolicyAndReschedule();
81 }
82 
83 void RealDevicePolicyProvider::OnSignalConnected(const string& interface_name,
84                                                  const string& signal_name,
85                                                  bool successful) {
86   if (!successful) {
87     LOG(WARNING) << "We couldn't connect to SessionManager signal for updates "
88                     "on the device policy blob. We will reload the policy file "
89                     "periodically.";
90   }
91   // We do a one-time refresh of the DevicePolicy just in case we missed a
92   // signal between the first refresh and the time the signal handler was
93   // actually connected.
94   RefreshDevicePolicy();
95 }
96 
97 void RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule() {
98   RefreshDevicePolicy();
99   scheduled_refresh_ = MessageLoop::current()->PostDelayedTask(
100       FROM_HERE,
101       base::Bind(&RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule,
102                  base::Unretained(this)),
103       TimeDelta::FromMinutes(kDevicePolicyRefreshRateInMinutes));
104 }
105 
106 template <typename T>
107 void RealDevicePolicyProvider::UpdateVariable(
108     AsyncCopyVariable<T>* var, bool (DevicePolicy::*getter_method)(T*) const) {
109   T new_value;
110   if (policy_provider_->device_policy_is_loaded() &&
111       (policy_provider_->GetDevicePolicy().*getter_method)(&new_value)) {
112     var->SetValue(new_value);
113   } else {
114     var->UnsetValue();
115   }
116 }
117 
118 template <typename T>
119 void RealDevicePolicyProvider::UpdateVariable(
120     AsyncCopyVariable<T>* var,
121     bool (RealDevicePolicyProvider::*getter_method)(T*) const) {
122   T new_value;
123   if (policy_provider_->device_policy_is_loaded() &&
124       (this->*getter_method)(&new_value)) {
125     var->SetValue(new_value);
126   } else {
127     var->UnsetValue();
128   }
129 }
130 
131 bool RealDevicePolicyProvider::ConvertRollbackToTargetVersion(
132     RollbackToTargetVersion* rollback_to_target_version) const {
133   int rollback_to_target_version_int;
134   if (!policy_provider_->GetDevicePolicy().GetRollbackToTargetVersion(
135           &rollback_to_target_version_int)) {
136     return false;
137   }
138   if (rollback_to_target_version_int < 0 ||
139       rollback_to_target_version_int >=
140           static_cast<int>(RollbackToTargetVersion::kMaxValue)) {
141     return false;
142   }
143   *rollback_to_target_version =
144       static_cast<RollbackToTargetVersion>(rollback_to_target_version_int);
145   return true;
146 }
147 
148 bool RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate(
149     set<ConnectionType>* allowed_types) const {
150   set<string> allowed_types_str;
151   if (!policy_provider_->GetDevicePolicy().GetAllowedConnectionTypesForUpdate(
152           &allowed_types_str)) {
153     return false;
154   }
155   allowed_types->clear();
156   for (auto& type_str : allowed_types_str) {
157     ConnectionType type =
158         chromeos_update_engine::connection_utils::ParseConnectionType(type_str);
159     if (type != ConnectionType::kUnknown) {
160       allowed_types->insert(type);
161     } else {
162       LOG(WARNING) << "Policy includes unknown connection type: " << type_str;
163     }
164   }
165   return true;
166 }
167 
168 bool RealDevicePolicyProvider::ConvertScatterFactor(
169     TimeDelta* scatter_factor) const {
170   int64_t scatter_factor_in_seconds;
171   if (!policy_provider_->GetDevicePolicy().GetScatterFactorInSeconds(
172           &scatter_factor_in_seconds)) {
173     return false;
174   }
175   if (scatter_factor_in_seconds < 0) {
176     LOG(WARNING) << "Ignoring negative scatter factor: "
177                  << scatter_factor_in_seconds;
178     return false;
179   }
180   *scatter_factor = TimeDelta::FromSeconds(scatter_factor_in_seconds);
181   return true;
182 }
183 
184 bool RealDevicePolicyProvider::ConvertDisallowedTimeIntervals(
185     WeeklyTimeIntervalVector* disallowed_intervals_out) const {
186   vector<DevicePolicy::WeeklyTimeInterval> parsed_intervals;
187   if (!policy_provider_->GetDevicePolicy().GetDisallowedTimeIntervals(
188           &parsed_intervals)) {
189     return false;
190   }
191 
192   disallowed_intervals_out->clear();
193   for (const auto& interval : parsed_intervals) {
194     disallowed_intervals_out->emplace_back(
195         WeeklyTime(interval.start_day_of_week, interval.start_time),
196         WeeklyTime(interval.end_day_of_week, interval.end_time));
197   }
198   return true;
199 }
200 
201 void RealDevicePolicyProvider::RefreshDevicePolicy() {
202   if (!policy_provider_->Reload()) {
203     LOG(INFO) << "No device policies/settings present.";
204   }
205 
206   var_device_policy_is_loaded_.SetValue(
207       policy_provider_->device_policy_is_loaded());
208 
209   UpdateVariable(&var_release_channel_, &DevicePolicy::GetReleaseChannel);
210   UpdateVariable(&var_release_channel_delegated_,
211                  &DevicePolicy::GetReleaseChannelDelegated);
212   UpdateVariable(&var_update_disabled_, &DevicePolicy::GetUpdateDisabled);
213   UpdateVariable(&var_target_version_prefix_,
214                  &DevicePolicy::GetTargetVersionPrefix);
215   UpdateVariable(&var_rollback_to_target_version_,
216                  &RealDevicePolicyProvider::ConvertRollbackToTargetVersion);
217   UpdateVariable(&var_rollback_allowed_milestones_,
218                  &DevicePolicy::GetRollbackAllowedMilestones);
219   if (policy_provider_->IsConsumerDevice()) {
220     // For consumer devices (which won't ever have policy), set value to 0.
221     var_rollback_allowed_milestones_.SetValue(0);
222   }
223   UpdateVariable(&var_scatter_factor_,
224                  &RealDevicePolicyProvider::ConvertScatterFactor);
225   UpdateVariable(
226       &var_allowed_connection_types_for_update_,
227       &RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate);
228   UpdateVariable(&var_owner_, &DevicePolicy::GetOwner);
229   UpdateVariable(&var_http_downloads_enabled_,
230                  &DevicePolicy::GetHttpDownloadsEnabled);
231   UpdateVariable(&var_au_p2p_enabled_, &DevicePolicy::GetAuP2PEnabled);
232   UpdateVariable(&var_allow_kiosk_app_control_chrome_version_,
233                  &DevicePolicy::GetAllowKioskAppControlChromeVersion);
234   UpdateVariable(&var_auto_launched_kiosk_app_id_,
235                  &DevicePolicy::GetAutoLaunchedKioskAppId);
236   UpdateVariable(&var_disallowed_time_intervals_,
237                  &RealDevicePolicyProvider::ConvertDisallowedTimeIntervals);
238 }
239 
240 }  // namespace chromeos_update_manager
241