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/connection_utils.h"
29 #include "update_engine/common/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
~RealDevicePolicyProvider()48 RealDevicePolicyProvider::~RealDevicePolicyProvider() {
49 MessageLoop::current()->CancelTask(scheduled_refresh_);
50 }
51
Init()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
OnPropertyChangedCompletedSignal(const string & success)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
OnSignalConnected(const string & interface_name,const string & signal_name,bool successful)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
RefreshDevicePolicyAndReschedule()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>
UpdateVariable(AsyncCopyVariable<T> * var,bool (DevicePolicy::* getter)(T *)const)107 void RealDevicePolicyProvider::UpdateVariable(
108 AsyncCopyVariable<T>* var,
109 // NOLINTNEXTLINE(readability/casting)
110 bool (DevicePolicy::*getter)(T*) const) {
111 T new_value;
112 if (policy_provider_->device_policy_is_loaded() &&
113 (policy_provider_->GetDevicePolicy().*getter)(&new_value)) {
114 var->SetValue(new_value);
115 } else {
116 var->UnsetValue();
117 }
118 }
119
120 template <typename T>
UpdateVariable(AsyncCopyVariable<T> * var,bool (RealDevicePolicyProvider::* getter)(T *)const)121 void RealDevicePolicyProvider::UpdateVariable(
122 AsyncCopyVariable<T>* var,
123 bool (RealDevicePolicyProvider::*getter)(T*) const) {
124 T new_value;
125 if (policy_provider_->device_policy_is_loaded() &&
126 (this->*getter)(&new_value)) {
127 var->SetValue(new_value);
128 } else {
129 var->UnsetValue();
130 }
131 }
132
ConvertRollbackToTargetVersion(RollbackToTargetVersion * rollback_to_target_version) const133 bool RealDevicePolicyProvider::ConvertRollbackToTargetVersion(
134 RollbackToTargetVersion* rollback_to_target_version) const {
135 int rollback_to_target_version_int;
136 if (!policy_provider_->GetDevicePolicy().GetRollbackToTargetVersion(
137 &rollback_to_target_version_int)) {
138 return false;
139 }
140 if (rollback_to_target_version_int < 0 ||
141 rollback_to_target_version_int >=
142 static_cast<int>(RollbackToTargetVersion::kMaxValue)) {
143 return false;
144 }
145 *rollback_to_target_version =
146 static_cast<RollbackToTargetVersion>(rollback_to_target_version_int);
147 return true;
148 }
149
ConvertAllowedConnectionTypesForUpdate(set<ConnectionType> * allowed_types) const150 bool RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate(
151 set<ConnectionType>* allowed_types) const {
152 set<string> allowed_types_str;
153 if (!policy_provider_->GetDevicePolicy().GetAllowedConnectionTypesForUpdate(
154 &allowed_types_str)) {
155 return false;
156 }
157 allowed_types->clear();
158 for (auto& type_str : allowed_types_str) {
159 ConnectionType type =
160 chromeos_update_engine::connection_utils::ParseConnectionType(type_str);
161 if (type != ConnectionType::kUnknown) {
162 allowed_types->insert(type);
163 } else {
164 LOG(WARNING) << "Policy includes unknown connection type: " << type_str;
165 }
166 }
167 return true;
168 }
169
ConvertScatterFactor(TimeDelta * scatter_factor) const170 bool RealDevicePolicyProvider::ConvertScatterFactor(
171 TimeDelta* scatter_factor) const {
172 int64_t scatter_factor_in_seconds;
173 if (!policy_provider_->GetDevicePolicy().GetScatterFactorInSeconds(
174 &scatter_factor_in_seconds)) {
175 return false;
176 }
177 if (scatter_factor_in_seconds < 0) {
178 LOG(WARNING) << "Ignoring negative scatter factor: "
179 << scatter_factor_in_seconds;
180 return false;
181 }
182 *scatter_factor = TimeDelta::FromSeconds(scatter_factor_in_seconds);
183 return true;
184 }
185
ConvertDisallowedTimeIntervals(WeeklyTimeIntervalVector * disallowed_intervals_out) const186 bool RealDevicePolicyProvider::ConvertDisallowedTimeIntervals(
187 WeeklyTimeIntervalVector* disallowed_intervals_out) const {
188 vector<DevicePolicy::WeeklyTimeInterval> parsed_intervals;
189 if (!policy_provider_->GetDevicePolicy().GetDisallowedTimeIntervals(
190 &parsed_intervals)) {
191 return false;
192 }
193
194 disallowed_intervals_out->clear();
195 for (const auto& interval : parsed_intervals) {
196 disallowed_intervals_out->emplace_back(
197 WeeklyTime(interval.start_day_of_week, interval.start_time),
198 WeeklyTime(interval.end_day_of_week, interval.end_time));
199 }
200 return true;
201 }
202
ConvertHasOwner(bool * has_owner) const203 bool RealDevicePolicyProvider::ConvertHasOwner(bool* has_owner) const {
204 string owner;
205 if (!policy_provider_->GetDevicePolicy().GetOwner(&owner)) {
206 return false;
207 }
208 *has_owner = !owner.empty();
209 return true;
210 }
211
ConvertChannelDowngradeBehavior(ChannelDowngradeBehavior * channel_downgrade_behavior) const212 bool RealDevicePolicyProvider::ConvertChannelDowngradeBehavior(
213 ChannelDowngradeBehavior* channel_downgrade_behavior) const {
214 int behavior;
215 if (!policy_provider_->GetDevicePolicy().GetChannelDowngradeBehavior(
216 &behavior)) {
217 return false;
218 }
219 if (behavior < static_cast<int>(ChannelDowngradeBehavior::kFirstValue) ||
220 behavior > static_cast<int>(ChannelDowngradeBehavior::kLastValue)) {
221 return false;
222 }
223 *channel_downgrade_behavior = static_cast<ChannelDowngradeBehavior>(behavior);
224 return true;
225 }
226
RefreshDevicePolicy()227 void RealDevicePolicyProvider::RefreshDevicePolicy() {
228 if (!policy_provider_->Reload()) {
229 LOG(INFO) << "No device policies/settings present.";
230 }
231
232 var_device_policy_is_loaded_.SetValue(
233 policy_provider_->device_policy_is_loaded());
234
235 UpdateVariable(&var_release_channel_, &DevicePolicy::GetReleaseChannel);
236 UpdateVariable(&var_release_channel_delegated_,
237 &DevicePolicy::GetReleaseChannelDelegated);
238 UpdateVariable(&var_release_lts_tag_, &DevicePolicy::GetReleaseLtsTag);
239 UpdateVariable(&var_update_disabled_, &DevicePolicy::GetUpdateDisabled);
240 UpdateVariable(&var_target_version_prefix_,
241 &DevicePolicy::GetTargetVersionPrefix);
242 UpdateVariable(&var_rollback_to_target_version_,
243 &RealDevicePolicyProvider::ConvertRollbackToTargetVersion);
244 UpdateVariable(&var_rollback_allowed_milestones_,
245 &DevicePolicy::GetRollbackAllowedMilestones);
246 if (policy_provider_->IsConsumerDevice()) {
247 // For consumer devices (which won't ever have policy), set value to 0.
248 var_rollback_allowed_milestones_.SetValue(0);
249 }
250 UpdateVariable(&var_scatter_factor_,
251 &RealDevicePolicyProvider::ConvertScatterFactor);
252 UpdateVariable(
253 &var_allowed_connection_types_for_update_,
254 &RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate);
255 UpdateVariable(&var_has_owner_, &RealDevicePolicyProvider::ConvertHasOwner);
256 UpdateVariable(&var_http_downloads_enabled_,
257 &DevicePolicy::GetHttpDownloadsEnabled);
258 UpdateVariable(&var_au_p2p_enabled_, &DevicePolicy::GetAuP2PEnabled);
259 UpdateVariable(&var_allow_kiosk_app_control_chrome_version_,
260 &DevicePolicy::GetAllowKioskAppControlChromeVersion);
261 UpdateVariable(&var_auto_launched_kiosk_app_id_,
262 &DevicePolicy::GetAutoLaunchedKioskAppId);
263 UpdateVariable(&var_disallowed_time_intervals_,
264 &RealDevicePolicyProvider::ConvertDisallowedTimeIntervals);
265 UpdateVariable(&var_channel_downgrade_behavior_,
266 &RealDevicePolicyProvider::ConvertChannelDowngradeBehavior);
267 UpdateVariable(&var_device_minimum_version_,
268 &DevicePolicy::GetHighestDeviceMinimumVersion);
269 UpdateVariable(&var_quick_fix_build_token_,
270 &DevicePolicy::GetDeviceQuickFixBuildToken);
271 }
272
273 } // namespace chromeos_update_manager
274