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 <base/location.h>
22 #include <base/logging.h>
23 #include <base/time/time.h>
24 #include <policy/device_policy.h>
25
26 #include "update_engine/common/utils.h"
27 #include "update_engine/connection_utils.h"
28 #include "update_engine/update_manager/generic_variables.h"
29
30 using base::TimeDelta;
31 using brillo::MessageLoop;
32 using chromeos_update_engine::ConnectionType;
33 using policy::DevicePolicy;
34 using std::set;
35 using std::string;
36
37 namespace {
38
39 const int kDevicePolicyRefreshRateInMinutes = 60;
40
41 } // namespace
42
43 namespace chromeos_update_manager {
44
~RealDevicePolicyProvider()45 RealDevicePolicyProvider::~RealDevicePolicyProvider() {
46 MessageLoop::current()->CancelTask(scheduled_refresh_);
47 }
48
Init()49 bool RealDevicePolicyProvider::Init() {
50 CHECK(policy_provider_ != nullptr);
51
52 // On Init() we try to get the device policy and keep updating it.
53 RefreshDevicePolicyAndReschedule();
54
55 #if USE_DBUS
56 // We also listen for signals from the session manager to force a device
57 // policy refresh.
58 session_manager_proxy_->RegisterPropertyChangeCompleteSignalHandler(
59 base::Bind(&RealDevicePolicyProvider::OnPropertyChangedCompletedSignal,
60 base::Unretained(this)),
61 base::Bind(&RealDevicePolicyProvider::OnSignalConnected,
62 base::Unretained(this)));
63 #endif // USE_DBUS
64 return true;
65 }
66
OnPropertyChangedCompletedSignal(const string & success)67 void RealDevicePolicyProvider::OnPropertyChangedCompletedSignal(
68 const string& success) {
69 if (success != "success") {
70 LOG(WARNING) << "Received device policy updated signal with a failure.";
71 }
72 // We refresh the policy file even if the payload string is kSignalFailure.
73 LOG(INFO) << "Reloading and re-scheduling device policy due to signal "
74 "received.";
75 MessageLoop::current()->CancelTask(scheduled_refresh_);
76 scheduled_refresh_ = MessageLoop::kTaskIdNull;
77 RefreshDevicePolicyAndReschedule();
78 }
79
OnSignalConnected(const string & interface_name,const string & signal_name,bool successful)80 void RealDevicePolicyProvider::OnSignalConnected(const string& interface_name,
81 const string& signal_name,
82 bool successful) {
83 if (!successful) {
84 LOG(WARNING) << "We couldn't connect to SessionManager signal for updates "
85 "on the device policy blob. We will reload the policy file "
86 "periodically.";
87 }
88 // We do a one-time refresh of the DevicePolicy just in case we missed a
89 // signal between the first refresh and the time the signal handler was
90 // actually connected.
91 RefreshDevicePolicy();
92 }
93
RefreshDevicePolicyAndReschedule()94 void RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule() {
95 RefreshDevicePolicy();
96 scheduled_refresh_ = MessageLoop::current()->PostDelayedTask(
97 FROM_HERE,
98 base::Bind(&RealDevicePolicyProvider::RefreshDevicePolicyAndReschedule,
99 base::Unretained(this)),
100 TimeDelta::FromMinutes(kDevicePolicyRefreshRateInMinutes));
101 }
102
103 template<typename T>
UpdateVariable(AsyncCopyVariable<T> * var,bool (DevicePolicy::* getter_method)(T *)const)104 void RealDevicePolicyProvider::UpdateVariable(
105 AsyncCopyVariable<T>* var,
106 bool (DevicePolicy::*getter_method)(T*) const) {
107 T new_value;
108 if (policy_provider_->device_policy_is_loaded() &&
109 (policy_provider_->GetDevicePolicy().*getter_method)(&new_value)) {
110 var->SetValue(new_value);
111 } else {
112 var->UnsetValue();
113 }
114 }
115
116 template<typename T>
UpdateVariable(AsyncCopyVariable<T> * var,bool (RealDevicePolicyProvider::* getter_method)(T *)const)117 void RealDevicePolicyProvider::UpdateVariable(
118 AsyncCopyVariable<T>* var,
119 bool (RealDevicePolicyProvider::*getter_method)(T*) const) {
120 T new_value;
121 if (policy_provider_->device_policy_is_loaded() &&
122 (this->*getter_method)(&new_value)) {
123 var->SetValue(new_value);
124 } else {
125 var->UnsetValue();
126 }
127 }
128
ConvertAllowedConnectionTypesForUpdate(set<ConnectionType> * allowed_types) const129 bool RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate(
130 set<ConnectionType>* allowed_types) const {
131 set<string> allowed_types_str;
132 if (!policy_provider_->GetDevicePolicy()
133 .GetAllowedConnectionTypesForUpdate(&allowed_types_str)) {
134 return false;
135 }
136 allowed_types->clear();
137 for (auto& type_str : allowed_types_str) {
138 ConnectionType type =
139 chromeos_update_engine::connection_utils::ParseConnectionType(type_str);
140 if (type != ConnectionType::kUnknown) {
141 allowed_types->insert(type);
142 } else {
143 LOG(WARNING) << "Policy includes unknown connection type: " << type_str;
144 }
145 }
146 return true;
147 }
148
ConvertScatterFactor(TimeDelta * scatter_factor) const149 bool RealDevicePolicyProvider::ConvertScatterFactor(
150 TimeDelta* scatter_factor) const {
151 int64_t scatter_factor_in_seconds;
152 if (!policy_provider_->GetDevicePolicy().GetScatterFactorInSeconds(
153 &scatter_factor_in_seconds)) {
154 return false;
155 }
156 if (scatter_factor_in_seconds < 0) {
157 LOG(WARNING) << "Ignoring negative scatter factor: "
158 << scatter_factor_in_seconds;
159 return false;
160 }
161 *scatter_factor = TimeDelta::FromSeconds(scatter_factor_in_seconds);
162 return true;
163 }
164
RefreshDevicePolicy()165 void RealDevicePolicyProvider::RefreshDevicePolicy() {
166 if (!policy_provider_->Reload()) {
167 LOG(INFO) << "No device policies/settings present.";
168 }
169
170 var_device_policy_is_loaded_.SetValue(
171 policy_provider_->device_policy_is_loaded());
172
173 UpdateVariable(&var_release_channel_, &DevicePolicy::GetReleaseChannel);
174 UpdateVariable(&var_release_channel_delegated_,
175 &DevicePolicy::GetReleaseChannelDelegated);
176 UpdateVariable(&var_update_disabled_, &DevicePolicy::GetUpdateDisabled);
177 UpdateVariable(&var_target_version_prefix_,
178 &DevicePolicy::GetTargetVersionPrefix);
179 UpdateVariable(&var_scatter_factor_,
180 &RealDevicePolicyProvider::ConvertScatterFactor);
181 UpdateVariable(
182 &var_allowed_connection_types_for_update_,
183 &RealDevicePolicyProvider::ConvertAllowedConnectionTypesForUpdate);
184 UpdateVariable(&var_owner_, &DevicePolicy::GetOwner);
185 UpdateVariable(&var_http_downloads_enabled_,
186 &DevicePolicy::GetHttpDownloadsEnabled);
187 UpdateVariable(&var_au_p2p_enabled_, &DevicePolicy::GetAuP2PEnabled);
188 UpdateVariable(&var_allow_kiosk_app_control_chrome_version_,
189 &DevicePolicy::GetAllowKioskAppControlChromeVersion);
190 }
191
192 } // namespace chromeos_update_manager
193