1 //
2 // Copyright (C) 2017 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/enterprise_device_policy_impl.h"
18 
19 #include "update_engine/common/utils.h"
20 
21 using std::string;
22 
23 namespace chromeos_update_manager {
24 
25 // Check to see if Enterprise-managed (has DevicePolicy) and/or Kiosk-mode.  If
26 // so, then defer to those settings.
UpdateCheckAllowed(EvaluationContext * ec,State * state,std::string * error,UpdateCheckParams * result) const27 EvalStatus EnterpriseDevicePolicyImpl::UpdateCheckAllowed(
28     EvaluationContext* ec,
29     State* state,
30     std::string* error,
31     UpdateCheckParams* result) const {
32   DevicePolicyProvider* const dp_provider = state->device_policy_provider();
33   SystemProvider* const system_provider = state->system_provider();
34 
35   const bool* device_policy_is_loaded_p =
36       ec->GetValue(dp_provider->var_device_policy_is_loaded());
37   if (device_policy_is_loaded_p && *device_policy_is_loaded_p) {
38     bool kiosk_app_control_chrome_version = false;
39 
40     // Check whether updates are disabled by policy.
41     const bool* update_disabled_p =
42         ec->GetValue(dp_provider->var_update_disabled());
43     if (update_disabled_p && *update_disabled_p) {
44       // Check whether allow kiosk app to control chrome version policy. This
45       // policy is only effective when AU is disabled by admin.
46       const bool* allow_kiosk_app_control_chrome_version_p = ec->GetValue(
47           dp_provider->var_allow_kiosk_app_control_chrome_version());
48       kiosk_app_control_chrome_version =
49           allow_kiosk_app_control_chrome_version_p &&
50           *allow_kiosk_app_control_chrome_version_p;
51       if (!kiosk_app_control_chrome_version) {
52         // No kiosk pin chrome version policy. AU is really disabled.
53         LOG(INFO) << "Updates disabled by policy, blocking update checks.";
54         return EvalStatus::kAskMeAgainLater;
55       }
56     }
57 
58     // By default, result->rollback_allowed is false.
59     if (kiosk_app_control_chrome_version) {
60       // Get the required platform version from Chrome.
61       const string* kiosk_required_platform_version_p =
62           ec->GetValue(system_provider->var_kiosk_required_platform_version());
63       if (!kiosk_required_platform_version_p) {
64         LOG(INFO) << "Kiosk app required platform version is not fetched, "
65                      "blocking update checks.";
66         return EvalStatus::kAskMeAgainLater;
67       } else if (kiosk_required_platform_version_p->empty()) {
68         // The platform version could not be fetched several times. Update
69         // based on |DeviceMinimumVersion| instead (crbug.com/1048931).
70         const base::Version* device_minimum_version_p =
71             ec->GetValue(dp_provider->var_device_minimum_version());
72         const base::Version* current_version_p(
73             ec->GetValue(system_provider->var_chromeos_version()));
74         if (device_minimum_version_p && device_minimum_version_p->IsValid() &&
75             current_version_p && current_version_p->IsValid() &&
76             *current_version_p > *device_minimum_version_p) {
77           // Do not update if the current version is newer than the minimum
78           // version.
79           LOG(INFO) << "Reading kiosk app required platform version failed "
80                        "repeatedly but current version is newer than "
81                        "DeviceMinimumVersion. Blocking update checks. "
82                        "Current version: "
83                     << *current_version_p
84                     << " DeviceMinimumVersion: " << *device_minimum_version_p;
85           return EvalStatus::kAskMeAgainLater;
86         }
87         LOG(WARNING) << "Reading kiosk app required platform version failed "
88                         "repeatedly. Attempting an update without it now.";
89         // An empty string for |target_version_prefix| allows arbitrary updates.
90         result->target_version_prefix = "";
91       } else {
92         result->target_version_prefix = *kiosk_required_platform_version_p;
93         LOG(INFO) << "Allow kiosk app to control Chrome version policy is set, "
94                   << "target version is " << result->target_version_prefix;
95       }
96       // TODO(hunyadym): Add support for allowing rollback using the manifest
97       // (if policy doesn't specify otherwise).
98     } else {
99       // Determine whether a target version prefix is dictated by policy.
100       const string* target_version_prefix_p =
101           ec->GetValue(dp_provider->var_target_version_prefix());
102       if (target_version_prefix_p)
103         result->target_version_prefix = *target_version_prefix_p;
104     }
105 
106     // Policy always overwrites whether rollback is allowed by the kiosk app
107     // manifest.
108     const RollbackToTargetVersion* rollback_to_target_version_p =
109         ec->GetValue(dp_provider->var_rollback_to_target_version());
110     if (rollback_to_target_version_p) {
111       switch (*rollback_to_target_version_p) {
112         case RollbackToTargetVersion::kUnspecified:
113           // We leave the default or the one specified by the kiosk app.
114           break;
115         case RollbackToTargetVersion::kDisabled:
116           LOG(INFO) << "Policy disables rollbacks.";
117           result->rollback_allowed = false;
118           result->rollback_data_save_requested = false;
119           break;
120         case RollbackToTargetVersion::kRollbackAndPowerwash:
121           LOG(INFO) << "Policy allows rollbacks with powerwash.";
122           result->rollback_allowed = true;
123           result->rollback_data_save_requested = false;
124           break;
125         case RollbackToTargetVersion::kRollbackAndRestoreIfPossible:
126           LOG(INFO)
127               << "Policy allows rollbacks, also tries to restore if possible.";
128           result->rollback_allowed = true;
129           result->rollback_data_save_requested = true;
130           break;
131         case RollbackToTargetVersion::kMaxValue:
132           NOTREACHED();
133           // Don't add a default case to let the compiler warn about newly
134           // added enum values which should be added here.
135       }
136     }
137 
138     // Determine allowed milestones for rollback
139     const int* rollback_allowed_milestones_p =
140         ec->GetValue(dp_provider->var_rollback_allowed_milestones());
141     if (rollback_allowed_milestones_p)
142       result->rollback_allowed_milestones = *rollback_allowed_milestones_p;
143 
144     // Determine whether a target channel is dictated by policy and whether we
145     // should rollback in case that channel is more stable.
146     const bool* release_channel_delegated_p =
147         ec->GetValue(dp_provider->var_release_channel_delegated());
148     if (release_channel_delegated_p && !(*release_channel_delegated_p)) {
149       const string* release_channel_p =
150           ec->GetValue(dp_provider->var_release_channel());
151       if (release_channel_p) {
152         result->target_channel = *release_channel_p;
153         const ChannelDowngradeBehavior* channel_downgrade_behavior_p =
154             ec->GetValue(dp_provider->var_channel_downgrade_behavior());
155         if (channel_downgrade_behavior_p &&
156             *channel_downgrade_behavior_p ==
157                 ChannelDowngradeBehavior::kRollback) {
158           result->rollback_on_channel_downgrade = true;
159         }
160       }
161     }
162 
163     const string* release_lts_tag_p =
164         ec->GetValue(dp_provider->var_release_lts_tag());
165     if (release_lts_tag_p) {
166       result->lts_tag = *release_lts_tag_p;
167     }
168 
169     const string* quick_fix_build_token_p =
170         ec->GetValue(dp_provider->var_quick_fix_build_token());
171     if (quick_fix_build_token_p) {
172       result->quick_fix_build_token = *quick_fix_build_token_p;
173     }
174   }
175   return EvalStatus::kContinue;
176 }
177 
178 }  // namespace chromeos_update_manager
179