aboutsummaryrefslogtreecommitdiffstats
path: root/policy
diff options
context:
space:
mode:
authorSen Jiang <senj@google.com>2018-08-09 16:52:23 -0700
committerSen Jiang <senj@google.com>2018-08-10 11:07:06 -0700
commit0fa01c38cc2beff8d7e11e4b512692ecdb640ca8 (patch)
tree279e9e692e3a7db704f65e6d3977e43e8e75b46a /policy
parentb5f20f52ab0885f1676b1c2024df541b3e6cc5f5 (diff)
parent904c2c9cd8d5ff06783030fb27ee23dcff743035 (diff)
downloadplatform_external_libbrillo-0fa01c38cc2beff8d7e11e4b512692ecdb640ca8.tar.gz
platform_external_libbrillo-0fa01c38cc2beff8d7e11e4b512692ecdb640ca8.tar.bz2
platform_external_libbrillo-0fa01c38cc2beff8d7e11e4b512692ecdb640ca8.zip
Merge remote-tracking branch 'aosp/upstream-master' into aosp/master.android-o-mr1-iot-release-1.0.4
Merge Chromium ToT to AOSP: git fetch aosp upstream-master git merge -X patience aosp/upstream-master Bug: 112326236 Test: libbrillo_test Change-Id: I35fbbddad556b051ce12b9cdd95bb2afef3cf6af
Diffstat (limited to 'policy')
-rw-r--r--policy/device_policy.h77
-rw-r--r--policy/device_policy_impl.cc283
-rw-r--r--policy/device_policy_impl.h38
-rw-r--r--policy/libpolicy.cc48
-rw-r--r--policy/libpolicy.h16
-rw-r--r--policy/mock_device_policy.h10
-rw-r--r--policy/mock_libpolicy.h1
-rw-r--r--policy/tests/device_policy_impl_unittest.cc250
-rw-r--r--policy/tests/libpolicy_unittest.cc269
-rw-r--r--policy/tests/policy_util_unittest.cc6
-rw-r--r--policy/tests/resilient_policy_util_unittest.cc12
-rw-r--r--policy/tests/whitelist/policy_allbin929 -> 1203 bytes
12 files changed, 879 insertions, 131 deletions
diff --git a/policy/device_policy.h b/policy/device_policy.h
index 2a3cb4b..5913d8c 100644
--- a/policy/device_policy.h
+++ b/policy/device_policy.h
@@ -9,9 +9,11 @@
#include <set>
#include <string>
+#include <utility>
#include <vector>
#include <base/macros.h>
+#include <base/time/time.h>
#pragma GCC visibility push(default)
@@ -35,10 +37,35 @@ class DevicePolicy {
uint16_t product_id;
};
+ // Time interval represented by two |day_of_week| and |time| pairs. The start
+ // of the interval is inclusive and the end is exclusive. The time represented
+ // by those pairs will be interpreted to be in the local timezone. Because of
+ // this, there exists the possibility of intervals being repeated or skipped
+ // in a day with daylight savings transitions, this is expected behavior.
+ struct WeeklyTimeInterval {
+ // Value is from 1 to 7 (1 = Monday, 2 = Tuesday, etc.). All values outside
+ // this range are invalid and will be discarded.
+ int start_day_of_week;
+ // Time since the start of the day. This value will be interpreted to be in
+ // the system's current timezone when used for range checking.
+ base::TimeDelta start_time;
+ int end_day_of_week;
+ base::TimeDelta end_time;
+ };
+
+ // Identifies a <day, percentage> pair in a staging schedule.
+ struct DayPercentagePair {
+ bool operator==(const DayPercentagePair& other) const {
+ return days == other.days && percentage == other.percentage;
+ }
+ int days;
+ int percentage;
+ };
+
DevicePolicy();
virtual ~DevicePolicy();
- // Load the signed policy off of disk into |policy_|.
+ // Load device policy off of disk into |policy_|.
// Returns true unless there is a policy on disk and loading it fails.
virtual bool LoadPolicy() = 0;
@@ -90,7 +117,7 @@ class DevicePolicy {
// Writes the value of the EphemeralUsersEnabled policy in
// |ephemeral_users_enabled|. Returns true on success.
virtual bool GetEphemeralUsersEnabled(
- bool* ephemeral_users_enabled) const = 0;
+ bool* ephemeral_users_enabled) const = 0;
// Writes the value of the release channel policy in |release_channel|.
// Returns true on success.
@@ -110,6 +137,18 @@ class DevicePolicy {
virtual bool GetTargetVersionPrefix(
std::string* target_version_prefix) const = 0;
+ // Writes the value of the rollback_to_target_version policy in
+ // |rollback_to_target_version|. |rollback_to_target_version| will be one of
+ // the values in AutoUpdateSettingsProto's RollbackToTargetVersion enum.
+ // Returns true on success.
+ virtual bool GetRollbackToTargetVersion(
+ int* rollback_to_target_version) const = 0;
+
+ // Writes the value of the rollback_allowed_milestones policy in
+ // |rollback_allowed_milestones|. Returns true on success.
+ virtual bool GetRollbackAllowedMilestones(
+ int* rollback_allowed_milestones) const = 0;
+
// Writes the value of the scatter_factor_in_seconds policy in
// |scatter_factor_in_seconds|. Returns true on success.
virtual bool GetScatterFactorInSeconds(
@@ -152,8 +191,38 @@ class DevicePolicy {
// Writes the value of the kiosk app id into |app_id_out|.
// Only succeeds if the device is in auto-launched kiosk mode.
- virtual bool GetAutoLaunchedKioskAppId(
- std::string* app_id_out) const = 0;
+ virtual bool GetAutoLaunchedKioskAppId(std::string* app_id_out) const = 0;
+
+ // Returns true if the policy data indicates that the device is enterprise
+ // managed. Note that this potentially could be faked by an exploit, therefore
+ // InstallAttributesReader must be used when tamper-proof evidence of the
+ // management state is required.
+ virtual bool IsEnterpriseManaged() const = 0;
+
+ // Writes the value of the DeviceSecondFactorAuthentication policy in
+ // |mode_out|. |mode_out| is one of the values from
+ // DeviceSecondFactorAuthenticationProto's U2fMode enum (e.g. DISABLED,
+ // U2F or U2F_EXTENDED). Returns true on success.
+ virtual bool GetSecondFactorAuthenticationMode(int* mode_out) const = 0;
+
+ // Writes the valid time intervals to |intervals_out|. These
+ // intervals are taken from the disallowed time intervals field in the
+ // AutoUpdateSettingsProto. Returns true if the intervals in the proto are
+ // valid.
+ virtual bool GetDisallowedTimeIntervals(
+ std::vector<WeeklyTimeInterval>* intervals_out) const = 0;
+
+ // Writes the value of the DeviceUpdateStagingSchedule policy to
+ // |staging_schedule_out|. Returns true on success.
+ // The schedule is a list of <days, percentage> pairs. The percentages are
+ // expected to be mononically increasing in the range of [1, 100]. Similarly,
+ // days are expected to be monotonically increasing in the range [1, 28]. Each
+ // pair describes the |percentage| of the fleet that is expected to receive an
+ // update after |days| days after an update was discovered. e.g. [<4, 30>, <8,
+ // 100>] means that 30% of devices should be updated in the first 4 days, and
+ // then 100% should be updated after 8 days.
+ virtual bool GetDeviceUpdateStagingSchedule(
+ std::vector<DayPercentagePair>* staging_schedule_out) const = 0;
private:
// Verifies that the policy signature is correct.
diff --git a/policy/device_policy_impl.cc b/policy/device_policy_impl.cc
index ec52be6..76b82a1 100644
--- a/policy/device_policy_impl.cc
+++ b/policy/device_policy_impl.cc
@@ -4,26 +4,34 @@
#include "policy/device_policy_impl.h"
+#include <algorithm>
#include <memory>
+#include <set>
+#include <string>
#include <base/containers/adapters.h>
#include <base/files/file_util.h>
+#include <base/json/json_reader.h>
#include <base/logging.h>
#include <base/macros.h>
#include <base/memory/ptr_util.h>
+#include <base/time/time.h>
+#include <base/values.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
-#include <set>
-#include <string>
-
#include "bindings/chrome_device_policy.pb.h"
#include "bindings/device_management_backend.pb.h"
#include "policy/policy_util.h"
#include "policy/resilient_policy_util.h"
+namespace em = enterprise_management;
+
namespace policy {
+// Maximum value of RollbackAllowedMilestones policy.
+const int kMaxRollbackAllowedMilestones = 4;
+
namespace {
const char kPolicyPath[] = "/var/lib/whitelist/policy";
const char kPublicKeyPath[] = "/var/lib/whitelist/owner.key";
@@ -93,12 +101,76 @@ std::string DecodeConnectionType(int type) {
return kConnectionTypes[type];
}
+// TODO(adokar): change type to base::Optional<int> when available.
+int ConvertDayOfWeekStringToInt(const std::string& day_of_week_str) {
+ if (day_of_week_str == "Sunday") return 0;
+ if (day_of_week_str == "Monday") return 1;
+ if (day_of_week_str == "Tuesday") return 2;
+ if (day_of_week_str == "Wednesday") return 3;
+ if (day_of_week_str == "Thursday") return 4;
+ if (day_of_week_str == "Friday") return 5;
+ if (day_of_week_str == "Saturday") return 6;
+ return -1;
+}
+
+bool DecodeWeeklyTimeFromValue(const base::DictionaryValue& dict_value,
+ int* day_of_week_out,
+ base::TimeDelta* time_out) {
+ std::string day_of_week_str;
+ if (!dict_value.GetString("day_of_week", &day_of_week_str)) {
+ LOG(ERROR) << "Day of the week is absent.";
+ return false;
+ }
+ *day_of_week_out = ConvertDayOfWeekStringToInt(day_of_week_str);
+ if (*day_of_week_out == -1) {
+ LOG(ERROR) << "Undefined day of the week: " << day_of_week_str;
+ return false;
+ }
+
+ int hours;
+ if (!dict_value.GetInteger("hours", &hours) || hours < 0 || hours > 23) {
+ LOG(ERROR) << "Hours are absent or are outside of the range [0, 24).";
+ return false;
+ }
+
+ int minutes;
+ if (!dict_value.GetInteger("minutes", &minutes) || minutes < 0 ||
+ minutes > 59) {
+ LOG(ERROR) << "Minutes are absent or are outside the range [0, 60)";
+ return false;
+ }
+
+ *time_out =
+ base::TimeDelta::FromMinutes(minutes) + base::TimeDelta::FromHours(hours);
+ return true;
+}
+
+std::unique_ptr<base::ListValue> DecodeListValueFromJSON(
+ const std::string& json_string) {
+ std::string error;
+ std::unique_ptr<base::Value> decoded_json =
+ base::JSONReader::ReadAndReturnError(json_string,
+ base::JSON_ALLOW_TRAILING_COMMAS,
+ nullptr, &error);
+ if (!decoded_json) {
+ LOG(ERROR) << "Invalid JSON string: " << error;
+ return nullptr;
+ }
+
+ std::unique_ptr<base::ListValue> list_val =
+ base::ListValue::From(std::move(decoded_json));
+ if (!list_val) {
+ LOG(ERROR) << "JSON string is not a list";
+ return nullptr;
+ }
+
+ return list_val;
+}
+
} // namespace
DevicePolicyImpl::DevicePolicyImpl()
- : policy_path_(kPolicyPath),
- keyfile_path_(kPublicKeyPath),
- verify_root_ownership_(true) {}
+ : policy_path_(kPolicyPath), keyfile_path_(kPublicKeyPath) {}
DevicePolicyImpl::~DevicePolicyImpl() {}
@@ -136,8 +208,7 @@ bool DevicePolicyImpl::GetUserWhitelist(
std::vector<std::string>* user_whitelist) const {
if (!device_policy_.has_user_whitelist())
return false;
- const enterprise_management::UserWhitelistProto& proto =
- device_policy_.user_whitelist();
+ const em::UserWhitelistProto& proto = device_policy_.user_whitelist();
user_whitelist->clear();
for (int i = 0; i < proto.user_whitelist_size(); i++)
user_whitelist->push_back(proto.user_whitelist(i));
@@ -192,8 +263,7 @@ bool DevicePolicyImpl::GetReportVersionInfo(bool* report_version_info) const {
if (!device_policy_.has_device_reporting())
return false;
- const enterprise_management::DeviceReportingProto& proto =
- device_policy_.device_reporting();
+ const em::DeviceReportingProto& proto = device_policy_.device_reporting();
if (!proto.has_report_version_info())
return false;
@@ -206,8 +276,7 @@ bool DevicePolicyImpl::GetReportActivityTimes(
if (!device_policy_.has_device_reporting())
return false;
- const enterprise_management::DeviceReportingProto& proto =
- device_policy_.device_reporting();
+ const em::DeviceReportingProto& proto = device_policy_.device_reporting();
if (!proto.has_report_activity_times())
return false;
@@ -219,8 +288,7 @@ bool DevicePolicyImpl::GetReportBootMode(bool* report_boot_mode) const {
if (!device_policy_.has_device_reporting())
return false;
- const enterprise_management::DeviceReportingProto& proto =
- device_policy_.device_reporting();
+ const em::DeviceReportingProto& proto = device_policy_.device_reporting();
if (!proto.has_report_boot_mode())
return false;
@@ -241,8 +309,7 @@ bool DevicePolicyImpl::GetReleaseChannel(std::string* release_channel) const {
if (!device_policy_.has_release_channel())
return false;
- const enterprise_management::ReleaseChannelProto& proto =
- device_policy_.release_channel();
+ const em::ReleaseChannelProto& proto = device_policy_.release_channel();
if (!proto.has_release_channel())
return false;
@@ -255,8 +322,7 @@ bool DevicePolicyImpl::GetReleaseChannelDelegated(
if (!device_policy_.has_release_channel())
return false;
- const enterprise_management::ReleaseChannelProto& proto =
- device_policy_.release_channel();
+ const em::ReleaseChannelProto& proto = device_policy_.release_channel();
if (!proto.has_release_channel_delegated())
return false;
@@ -268,7 +334,7 @@ bool DevicePolicyImpl::GetUpdateDisabled(bool* update_disabled) const {
if (!device_policy_.has_auto_update_settings())
return false;
- const enterprise_management::AutoUpdateSettingsProto& proto =
+ const em::AutoUpdateSettingsProto& proto =
device_policy_.auto_update_settings();
if (!proto.has_update_disabled())
return false;
@@ -282,7 +348,7 @@ bool DevicePolicyImpl::GetTargetVersionPrefix(
if (!device_policy_.has_auto_update_settings())
return false;
- const enterprise_management::AutoUpdateSettingsProto& proto =
+ const em::AutoUpdateSettingsProto& proto =
device_policy_.auto_update_settings();
if (!proto.has_target_version_prefix())
return false;
@@ -291,12 +357,58 @@ bool DevicePolicyImpl::GetTargetVersionPrefix(
return true;
}
+bool DevicePolicyImpl::GetRollbackToTargetVersion(
+ int* rollback_to_target_version) const {
+ if (!device_policy_.has_auto_update_settings())
+ return false;
+
+ const em::AutoUpdateSettingsProto& proto =
+ device_policy_.auto_update_settings();
+ if (!proto.has_rollback_to_target_version())
+ return false;
+
+ *rollback_to_target_version = proto.rollback_to_target_version();
+ return true;
+}
+
+bool DevicePolicyImpl::GetRollbackAllowedMilestones(
+ int* rollback_allowed_milestones) const {
+ // This policy can be only set for devices which are enterprise enrolled.
+ if (!install_attributes_reader_->IsLocked())
+ return false;
+ if (install_attributes_reader_->GetAttribute(
+ InstallAttributesReader::kAttrMode) !=
+ InstallAttributesReader::kDeviceModeEnterprise &&
+ install_attributes_reader_->GetAttribute(
+ InstallAttributesReader::kAttrMode) !=
+ InstallAttributesReader::kDeviceModeEnterpriseAD)
+ return false;
+
+ if (device_policy_.has_auto_update_settings()) {
+ const em::AutoUpdateSettingsProto& proto =
+ device_policy_.auto_update_settings();
+ if (proto.has_rollback_allowed_milestones()) {
+ // Policy is set, enforce minimum and maximum constraints.
+ *rollback_allowed_milestones = proto.rollback_allowed_milestones();
+ if (*rollback_allowed_milestones < 0)
+ *rollback_allowed_milestones = 0;
+ if (*rollback_allowed_milestones > kMaxRollbackAllowedMilestones)
+ *rollback_allowed_milestones = kMaxRollbackAllowedMilestones;
+ return true;
+ }
+ }
+ // Policy is not present, use default for enterprise devices.
+ VLOG(1) << "RollbackAllowedMilestones policy is not set, using default 0.";
+ *rollback_allowed_milestones = 0;
+ return true;
+}
+
bool DevicePolicyImpl::GetScatterFactorInSeconds(
int64_t* scatter_factor_in_seconds) const {
if (!device_policy_.has_auto_update_settings())
return false;
- const enterprise_management::AutoUpdateSettingsProto& proto =
+ const em::AutoUpdateSettingsProto& proto =
device_policy_.auto_update_settings();
if (!proto.has_scatter_factor_in_seconds())
return false;
@@ -310,7 +422,7 @@ bool DevicePolicyImpl::GetAllowedConnectionTypesForUpdate(
if (!device_policy_.has_auto_update_settings())
return false;
- const enterprise_management::AutoUpdateSettingsProto& proto =
+ const em::AutoUpdateSettingsProto& proto =
device_policy_.auto_update_settings();
if (proto.allowed_connection_types_size() <= 0)
return false;
@@ -328,7 +440,7 @@ bool DevicePolicyImpl::GetOpenNetworkConfiguration(
if (!device_policy_.has_open_network_configuration())
return false;
- const enterprise_management::DeviceOpenNetworkConfigurationProto& proto =
+ const em::DeviceOpenNetworkConfigurationProto& proto =
device_policy_.open_network_configuration();
if (!proto.has_open_network_configuration())
return false;
@@ -338,11 +450,11 @@ bool DevicePolicyImpl::GetOpenNetworkConfiguration(
}
bool DevicePolicyImpl::GetOwner(std::string* owner) const {
- // The device is enterprise enrolled iff a request token exists.
- if (policy_data_.has_request_token()) {
+ if (IsEnterpriseManaged()) {
*owner = "";
return true;
}
+
if (!policy_data_.has_username())
return false;
*owner = policy_data_.username();
@@ -354,7 +466,7 @@ bool DevicePolicyImpl::GetHttpDownloadsEnabled(
if (!device_policy_.has_auto_update_settings())
return false;
- const enterprise_management::AutoUpdateSettingsProto& proto =
+ const em::AutoUpdateSettingsProto& proto =
device_policy_.auto_update_settings();
if (!proto.has_http_downloads_enabled())
@@ -368,7 +480,7 @@ bool DevicePolicyImpl::GetAuP2PEnabled(bool* au_p2p_enabled) const {
if (!device_policy_.has_auto_update_settings())
return false;
- const enterprise_management::AutoUpdateSettingsProto& proto =
+ const em::AutoUpdateSettingsProto& proto =
device_policy_.auto_update_settings();
if (!proto.has_p2p_enabled())
@@ -383,7 +495,7 @@ bool DevicePolicyImpl::GetAllowKioskAppControlChromeVersion(
if (!device_policy_.has_allow_kiosk_app_control_chrome_version())
return false;
- const enterprise_management::AllowKioskAppControlChromeVersionProto& proto =
+ const em::AllowKioskAppControlChromeVersionProto& proto =
device_policy_.allow_kiosk_app_control_chrome_version();
if (!proto.has_allow_kiosk_app_control_chrome_version())
@@ -398,11 +510,11 @@ bool DevicePolicyImpl::GetUsbDetachableWhitelist(
std::vector<UsbDeviceId>* usb_whitelist) const {
if (!device_policy_.has_usb_detachable_whitelist())
return false;
- const enterprise_management::UsbDetachableWhitelistProto& proto =
+ const em::UsbDetachableWhitelistProto& proto =
device_policy_.usb_detachable_whitelist();
usb_whitelist->clear();
for (int i = 0; i < proto.id_size(); i++) {
- const ::enterprise_management::UsbDeviceIdProto& id = proto.id(i);
+ const em::UsbDeviceIdProto& id = proto.id(i);
UsbDeviceId dev_id;
dev_id.vendor_id = id.has_vendor_id() ? id.vendor_id() : 0;
dev_id.product_id = id.has_product_id() ? id.product_id() : 0;
@@ -411,12 +523,46 @@ bool DevicePolicyImpl::GetUsbDetachableWhitelist(
return true;
}
+bool DevicePolicyImpl::GetDeviceUpdateStagingSchedule(
+ std::vector<DayPercentagePair>* staging_schedule_out) const {
+ staging_schedule_out->clear();
+
+ if (!device_policy_.has_auto_update_settings())
+ return false;
+
+ const em::AutoUpdateSettingsProto &proto =
+ device_policy_.auto_update_settings();
+
+ if (!proto.has_staging_schedule())
+ return false;
+
+ std::unique_ptr<base::ListValue> list_val =
+ DecodeListValueFromJSON(proto.staging_schedule());
+ if (!list_val)
+ return false;
+
+ for (base::Value* const& pair_value : *list_val) {
+ base::DictionaryValue* day_percentage_pair;
+ if (!pair_value->GetAsDictionary(&day_percentage_pair))
+ return false;
+ int days, percentage;
+ if (!day_percentage_pair->GetInteger("days", &days) ||
+ !day_percentage_pair->GetInteger("percentage", &percentage))
+ return false;
+ // Limit the percentage to [0, 100] and days to [1, 28];
+ staging_schedule_out->push_back({std::max(std::min(days, 28), 1),
+ std::max(std::min(percentage, 100), 0)});
+ }
+
+ return true;
+}
+
bool DevicePolicyImpl::GetAutoLaunchedKioskAppId(
std::string* app_id_out) const {
if (!device_policy_.has_device_local_accounts())
return false;
- const enterprise_management::DeviceLocalAccountsProto& local_accounts =
+ const em::DeviceLocalAccountsProto& local_accounts =
device_policy_.device_local_accounts();
// For auto-launched kiosk apps, the delay needs to be 0.
@@ -424,7 +570,7 @@ bool DevicePolicyImpl::GetAutoLaunchedKioskAppId(
local_accounts.auto_login_delay() != 0)
return false;
- for (const enterprise_management::DeviceLocalAccountInfoProto& account :
+ for (const em::DeviceLocalAccountInfoProto& account :
local_accounts.account()) {
// If this isn't an auto-login account, move to the next one.
if (account.account_id() != local_accounts.auto_login_id())
@@ -433,8 +579,7 @@ bool DevicePolicyImpl::GetAutoLaunchedKioskAppId(
// If the auto-launched account is not a kiosk app, bail out, we aren't
// running in auto-launched kiosk mode.
if (account.type() !=
- enterprise_management::DeviceLocalAccountInfoProto::
- ACCOUNT_TYPE_KIOSK_APP) {
+ em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_KIOSK_APP) {
return false;
}
@@ -446,6 +591,74 @@ bool DevicePolicyImpl::GetAutoLaunchedKioskAppId(
return false;
}
+bool DevicePolicyImpl::IsEnterpriseManaged() const {
+ if (policy_data_.has_management_mode())
+ return policy_data_.management_mode() == em::PolicyData::ENTERPRISE_MANAGED;
+ // Fall back to checking the request token, see management_mode documentation
+ // in device_management_backend.proto.
+ return policy_data_.has_request_token();
+}
+
+bool DevicePolicyImpl::GetSecondFactorAuthenticationMode(int* mode_out) const {
+ if (!device_policy_.has_device_second_factor_authentication())
+ return false;
+
+ const em::DeviceSecondFactorAuthenticationProto& proto =
+ device_policy_.device_second_factor_authentication();
+
+ if (!proto.has_mode())
+ return false;
+
+ *mode_out = proto.mode();
+ return true;
+}
+
+bool DevicePolicyImpl::GetDisallowedTimeIntervals(
+ std::vector<WeeklyTimeInterval>* intervals_out) const {
+ intervals_out->clear();
+
+ if (!device_policy_.has_auto_update_settings()) {
+ return false;
+ }
+
+ const em::AutoUpdateSettingsProto& proto =
+ device_policy_.auto_update_settings();
+
+ if (!proto.has_disallowed_time_intervals()) {
+ return false;
+ }
+
+ std::unique_ptr<base::ListValue> list_val =
+ DecodeListValueFromJSON(proto.disallowed_time_intervals());
+ if (!list_val)
+ return false;
+
+ for (base::Value* const& interval_value : *list_val) {
+ base::DictionaryValue* interval_dict;
+ if (!interval_value->GetAsDictionary(&interval_dict)) {
+ LOG(ERROR) << "Invalid JSON string given. Interval is not a dict.";
+ return false;
+ }
+ base::DictionaryValue* start;
+ base::DictionaryValue* end;
+ if (!interval_dict->GetDictionary("start", &start) ||
+ !interval_dict->GetDictionary("end", &end)) {
+ LOG(ERROR) << "Interval is missing start/end.";
+ return false;
+ }
+ WeeklyTimeInterval weekly_interval;
+ if (!DecodeWeeklyTimeFromValue(*start, &weekly_interval.start_day_of_week,
+ &weekly_interval.start_time) ||
+ !DecodeWeeklyTimeFromValue(*end, &weekly_interval.end_day_of_week,
+ &weekly_interval.end_time)) {
+ return false;
+ }
+
+ intervals_out->push_back(weekly_interval);
+ }
+ return true;
+}
+
bool DevicePolicyImpl::VerifyPolicyFile(const base::FilePath& policy_path) {
if (!verify_root_ownership_) {
return true;
@@ -506,7 +719,7 @@ bool DevicePolicyImpl::LoadPolicyFromFile(const base::FilePath& policy_path) {
return false;
}
- bool verify_policy = true;
+ bool verify_policy = verify_policy_;
if (!install_attributes_reader_) {
install_attributes_reader_ = std::make_unique<InstallAttributesReader>();
}
diff --git a/policy/device_policy_impl.h b/policy/device_policy_impl.h
index b178e28..6891312 100644
--- a/policy/device_policy_impl.h
+++ b/policy/device_policy_impl.h
@@ -5,8 +5,10 @@
#ifndef LIBBRILLO_POLICY_DEVICE_POLICY_IMPL_H_
#define LIBBRILLO_POLICY_DEVICE_POLICY_IMPL_H_
+#include <memory>
#include <set>
#include <string>
+#include <utility>
#include <vector>
#include <base/files/file_path.h>
@@ -14,6 +16,7 @@
#include "bindings/chrome_device_policy.pb.h"
#include "bindings/device_management_backend.pb.h"
+#include "install_attributes/libinstallattributes.h"
#include "policy/device_policy.h"
#pragma GCC visibility push(default)
@@ -30,6 +33,12 @@ class DevicePolicyImpl : public DevicePolicy {
DevicePolicyImpl();
~DevicePolicyImpl() override;
+ const enterprise_management::ChromeDeviceSettingsProto& get_device_policy()
+ const {
+ return device_policy_;
+ }
+
+ // DevicePolicy overrides:
bool LoadPolicy() override;
bool GetPolicyRefreshRate(int* rate) const override;
bool GetUserWhitelist(
@@ -50,6 +59,10 @@ class DevicePolicyImpl : public DevicePolicy {
bool GetUpdateDisabled(bool* update_disabled) const override;
bool GetTargetVersionPrefix(
std::string* target_version_prefix) const override;
+ bool GetRollbackToTargetVersion(
+ int* rollback_to_target_version) const override;
+ bool GetRollbackAllowedMilestones(
+ int* rollback_allowed_milestones) const override;
bool GetScatterFactorInSeconds(
int64_t* scatter_factor_in_seconds) const override;
bool GetAllowedConnectionTypesForUpdate(
@@ -64,6 +77,12 @@ class DevicePolicyImpl : public DevicePolicy {
bool GetUsbDetachableWhitelist(
std::vector<UsbDeviceId>* usb_whitelist) const override;
bool GetAutoLaunchedKioskAppId(std::string* app_id_out) const override;
+ bool IsEnterpriseManaged() const override;
+ bool GetSecondFactorAuthenticationMode(int* mode_out) const override;
+ bool GetDisallowedTimeIntervals(
+ std::vector<WeeklyTimeInterval>* intervals_out) const override;
+ bool GetDeviceUpdateStagingSchedule(
+ std::vector<DayPercentagePair> *staging_schedule_out) const override;
// Methods that can be used only for testing.
void set_policy_data_for_testing(
@@ -77,12 +96,17 @@ class DevicePolicyImpl : public DevicePolicy {
std::unique_ptr<InstallAttributesReader> install_attributes_reader) {
install_attributes_reader_ = std::move(install_attributes_reader);
}
+ void set_policy_for_testing(
+ const enterprise_management::ChromeDeviceSettingsProto& device_policy) {
+ device_policy_ = device_policy;
+ }
void set_policy_path_for_testing(const base::FilePath& policy_path) {
policy_path_ = policy_path;
}
void set_key_file_path_for_testing(const base::FilePath& keyfile_path) {
keyfile_path_ = keyfile_path;
}
+ void set_verify_policy_for_testing(bool value) { verify_policy_ = value; }
private:
// Verifies that both the policy file and the signature file exist and are
@@ -93,11 +117,14 @@ class DevicePolicyImpl : public DevicePolicy {
// Verifies that the policy signature is correct.
bool VerifyPolicySignature() override;
- // Loads the signed policy off of disk from |policy_path| into |policy_|.
- // Returns true if the |policy_path| is present on disk and loading it is
- // successful.
+ // Loads policy off of disk from |policy_path| into |policy_|. Returns true if
+ // the |policy_path| is present on disk and loading it is successful.
bool LoadPolicyFromFile(const base::FilePath& policy_path);
+ // Path of the default policy file, e.g. /path/to/policy. In order to make
+ // device policy more resilient against broken files, this class also tries to
+ // load indexed paths /path/to/policy.1, /path/to/policy.2 etc., see
+ // resilient_policy_utils.h.
base::FilePath policy_path_;
base::FilePath keyfile_path_;
std::unique_ptr<InstallAttributesReader> install_attributes_reader_;
@@ -107,7 +134,10 @@ class DevicePolicyImpl : public DevicePolicy {
// If true, verify that policy files are owned by root. True in production
// but can be set to false by tests.
- bool verify_root_ownership_;
+ bool verify_root_ownership_ = true;
+ // If false, all types of verification are disabled. True in production
+ // but can be set to false by tests.
+ bool verify_policy_ = true;
DISALLOW_COPY_AND_ASSIGN(DevicePolicyImpl);
};
diff --git a/policy/libpolicy.cc b/policy/libpolicy.cc
index 99fa46d..a0b7640 100644
--- a/policy/libpolicy.cc
+++ b/policy/libpolicy.cc
@@ -4,6 +4,8 @@
#include "policy/libpolicy.h"
+#include <memory>
+
#include <base/logging.h>
#include "policy/device_policy.h"
@@ -13,17 +15,23 @@
namespace policy {
-PolicyProvider::PolicyProvider()
- : device_policy_(nullptr),
- device_policy_is_loaded_(false) {
+PolicyProvider::PolicyProvider() {
#ifndef __ANDROID__
- device_policy_.reset(new DevicePolicyImpl());
+ device_policy_ = std::make_unique<DevicePolicyImpl>();
+ install_attributes_reader_ = std::make_unique<InstallAttributesReader>();
#endif
}
PolicyProvider::PolicyProvider(std::unique_ptr<DevicePolicy> device_policy)
: device_policy_(std::move(device_policy)),
- device_policy_is_loaded_(true) {}
+#ifdef __ANDROID__
+ device_policy_is_loaded_(true) {
+}
+#else
+ device_policy_is_loaded_(true),
+ install_attributes_reader_(std::make_unique<InstallAttributesReader>()) {
+}
+#endif // __ANDROID__
PolicyProvider::~PolicyProvider() {}
@@ -42,10 +50,34 @@ bool PolicyProvider::device_policy_is_loaded() const {
}
const DevicePolicy& PolicyProvider::GetDevicePolicy() const {
- if (!device_policy_is_loaded_)
- DCHECK("Trying to get policy data but policy was not loaded!");
-
+ DCHECK(device_policy_is_loaded_)
+ << "Trying to get policy data but policy was not loaded!";
return *device_policy_;
}
+bool PolicyProvider::IsConsumerDevice() const {
+#ifdef __ANDROID__
+ return true;
+#else
+ if (!install_attributes_reader_->IsLocked())
+ return false;
+
+ const std::string& device_mode = install_attributes_reader_->GetAttribute(
+ InstallAttributesReader::kAttrMode);
+ return device_mode != InstallAttributesReader::kDeviceModeEnterprise &&
+ device_mode != InstallAttributesReader::kDeviceModeEnterpriseAD;
+#endif // __ANDROID__
+}
+
+void PolicyProvider::SetDevicePolicyForTesting(
+ std::unique_ptr<DevicePolicy> device_policy) {
+ device_policy_ = std::move(device_policy);
+ device_policy_is_loaded_ = true;
+}
+
+void PolicyProvider::SetInstallAttributesReaderForTesting(
+ std::unique_ptr<InstallAttributesReader> install_attributes_reader) {
+ install_attributes_reader_ = std::move(install_attributes_reader);
+}
+
} // namespace policy
diff --git a/policy/libpolicy.h b/policy/libpolicy.h
index 1a411cf..5e87f58 100644
--- a/policy/libpolicy.h
+++ b/policy/libpolicy.h
@@ -10,6 +10,8 @@
#include <base/macros.h>
+#include "install_attributes/libinstallattributes.h"
+
#pragma GCC visibility push(default)
namespace policy {
@@ -22,6 +24,7 @@ class DevicePolicy;
// its signature.
class PolicyProvider {
public:
+ // The default constructor does not load policy.
PolicyProvider();
virtual ~PolicyProvider();
@@ -37,9 +40,20 @@ class PolicyProvider {
// Returns a value from the device policy cache.
virtual const DevicePolicy& GetDevicePolicy() const;
+ // Returns true if the device is not an enterprise enrolled device, so it
+ // won't have device policy before the next powerwash. Returns false if device
+ // is still in OOBE (so device mode is not determined yet).
+ virtual bool IsConsumerDevice() const;
+
+ void SetDevicePolicyForTesting(
+ std::unique_ptr<DevicePolicy> device_policy);
+ void SetInstallAttributesReaderForTesting(
+ std::unique_ptr<InstallAttributesReader> install_attributes_reader);
+
private:
std::unique_ptr<DevicePolicy> device_policy_;
- bool device_policy_is_loaded_;
+ bool device_policy_is_loaded_ = false;
+ std::unique_ptr<InstallAttributesReader> install_attributes_reader_;
DISALLOW_COPY_AND_ASSIGN(PolicyProvider);
};
diff --git a/policy/mock_device_policy.h b/policy/mock_device_policy.h
index 23e8147..90470e2 100644
--- a/policy/mock_device_policy.h
+++ b/policy/mock_device_policy.h
@@ -7,6 +7,7 @@
#include <set>
#include <string>
+#include <utility>
#include <vector>
#include <gmock/gmock.h>
@@ -82,6 +83,8 @@ class MockDevicePolicy : public DevicePolicy {
MOCK_CONST_METHOD1(GetUpdateDisabled,
bool(bool*)); // NOLINT(readability/function)
MOCK_CONST_METHOD1(GetTargetVersionPrefix, bool(std::string*));
+ MOCK_CONST_METHOD1(GetRollbackToTargetVersion, bool(int*));
+ MOCK_CONST_METHOD1(GetRollbackAllowedMilestones, bool(int*));
MOCK_CONST_METHOD1(GetScatterFactorInSeconds,
bool(int64_t*)); // NOLINT(readability/function)
MOCK_CONST_METHOD1(GetAllowedConnectionTypesForUpdate,
@@ -97,7 +100,12 @@ class MockDevicePolicy : public DevicePolicy {
MOCK_CONST_METHOD1(GetUsbDetachableWhitelist,
bool(std::vector<DevicePolicy::UsbDeviceId>*));
MOCK_CONST_METHOD1(GetAutoLaunchedKioskAppId, bool(std::string*));
-
+ MOCK_CONST_METHOD0(IsEnterpriseManaged, bool());
+ MOCK_CONST_METHOD1(GetSecondFactorAuthenticationMode, bool(int*));
+ MOCK_CONST_METHOD1(GetDisallowedTimeIntervals,
+ bool(std::vector<WeeklyTimeInterval>*));
+ MOCK_CONST_METHOD1(GetDeviceUpdateStagingSchedule,
+ bool(std::vector<DayPercentagePair>*));
MOCK_METHOD0(VerifyPolicyFiles, bool(void));
MOCK_METHOD0(VerifyPolicySignature, bool(void));
};
diff --git a/policy/mock_libpolicy.h b/policy/mock_libpolicy.h
index acb9b8b..a0f6920 100644
--- a/policy/mock_libpolicy.h
+++ b/policy/mock_libpolicy.h
@@ -23,6 +23,7 @@ class MockPolicyProvider : public PolicyProvider {
MOCK_METHOD0(Reload, bool(void));
MOCK_CONST_METHOD0(device_policy_is_loaded, bool(void));
MOCK_CONST_METHOD0(GetDevicePolicy, const DevicePolicy&(void));
+ MOCK_CONST_METHOD0(IsConsumerDevice, bool(void));
private:
DISALLOW_COPY_AND_ASSIGN(MockPolicyProvider);
diff --git a/policy/tests/device_policy_impl_unittest.cc b/policy/tests/device_policy_impl_unittest.cc
new file mode 100644
index 0000000..37c3916
--- /dev/null
+++ b/policy/tests/device_policy_impl_unittest.cc
@@ -0,0 +1,250 @@
+// Copyright 2017 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "policy/device_policy_impl.h"
+
+#include "bindings/chrome_device_policy.pb.h"
+#include "install_attributes/mock_install_attributes_reader.h"
+
+namespace em = enterprise_management;
+
+using testing::ElementsAre;
+
+namespace policy {
+
+class DevicePolicyImplTest : public testing::Test, public DevicePolicyImpl {
+ protected:
+ void InitializePolicy(const char* device_mode,
+ const em::ChromeDeviceSettingsProto& proto) {
+ device_policy_.set_policy_for_testing(proto);
+ device_policy_.set_install_attributes_for_testing(
+ std::make_unique<MockInstallAttributesReader>(
+ device_mode, true /* initialized */));
+ }
+
+ DevicePolicyImpl device_policy_;
+};
+
+// Enterprise managed.
+TEST_F(DevicePolicyImplTest, GetOwner_Managed) {
+ em::PolicyData policy_data;
+ policy_data.set_username("user@example.com");
+ policy_data.set_management_mode(em::PolicyData::ENTERPRISE_MANAGED);
+ device_policy_.set_policy_data_for_testing(policy_data);
+
+ std::string owner("something");
+ EXPECT_TRUE(device_policy_.GetOwner(&owner));
+ EXPECT_TRUE(owner.empty());
+}
+
+// Consumer owned.
+TEST_F(DevicePolicyImplTest, GetOwner_Consumer) {
+ em::PolicyData policy_data;
+ policy_data.set_username("user@example.com");
+ policy_data.set_management_mode(em::PolicyData::LOCAL_OWNER);
+ policy_data.set_request_token("codepath-must-ignore-dmtoken");
+ device_policy_.set_policy_data_for_testing(policy_data);
+
+ std::string owner;
+ EXPECT_TRUE(device_policy_.GetOwner(&owner));
+ EXPECT_EQ("user@example.com", owner);
+}
+
+// Consumer owned, username is missing.
+TEST_F(DevicePolicyImplTest, GetOwner_ConsumerMissingUsername) {
+ em::PolicyData policy_data;
+ device_policy_.set_policy_data_for_testing(policy_data);
+
+ std::string owner("something");
+ EXPECT_FALSE(device_policy_.GetOwner(&owner));
+ EXPECT_EQ("something", owner);
+}
+
+// Enterprise managed, denoted by management_mode.
+TEST_F(DevicePolicyImplTest, IsEnterpriseManaged_ManagementModeManaged) {
+ em::PolicyData policy_data;
+ policy_data.set_management_mode(em::PolicyData::ENTERPRISE_MANAGED);
+ device_policy_.set_policy_data_for_testing(policy_data);
+
+ EXPECT_TRUE(device_policy_.IsEnterpriseManaged());
+}
+
+// Enterprise managed, fallback to DM token.
+TEST_F(DevicePolicyImplTest, IsEnterpriseManaged_DMTokenManaged) {
+ em::PolicyData policy_data;
+ policy_data.set_request_token("abc");
+ device_policy_.set_policy_data_for_testing(policy_data);
+
+ EXPECT_TRUE(device_policy_.IsEnterpriseManaged());
+}
+
+// Consumer owned, denoted by management_mode.
+TEST_F(DevicePolicyImplTest, IsEnterpriseManaged_ManagementModeConsumer) {
+ em::PolicyData policy_data;
+ policy_data.set_management_mode(em::PolicyData::LOCAL_OWNER);
+ policy_data.set_request_token("codepath-must-ignore-dmtoken");
+ device_policy_.set_policy_data_for_testing(policy_data);
+
+ EXPECT_FALSE(device_policy_.IsEnterpriseManaged());
+}
+
+// Consumer owned, fallback to interpreting absence of DM token.
+TEST_F(DevicePolicyImplTest, IsEnterpriseManaged_DMTokenConsumer) {
+ em::PolicyData policy_data;
+ device_policy_.set_policy_data_for_testing(policy_data);
+
+ EXPECT_FALSE(device_policy_.IsEnterpriseManaged());
+}
+
+// RollbackAllowedMilestones is not set.
+TEST_F(DevicePolicyImplTest, GetRollbackAllowedMilestones_NotSet) {
+ device_policy_.set_install_attributes_for_testing(
+ std::make_unique<MockInstallAttributesReader>(
+ InstallAttributesReader::kDeviceModeEnterprise, true));
+
+ int value = -1;
+ ASSERT_TRUE(device_policy_.GetRollbackAllowedMilestones(&value));
+ EXPECT_EQ(0, value);
+}
+
+// RollbackAllowedMilestones is set to a valid value.
+TEST_F(DevicePolicyImplTest, GetRollbackAllowedMilestones_Set) {
+ em::ChromeDeviceSettingsProto device_policy_proto;
+ em::AutoUpdateSettingsProto* auto_update_settings =
+ device_policy_proto.mutable_auto_update_settings();
+ auto_update_settings->set_rollback_allowed_milestones(3);
+ InitializePolicy(InstallAttributesReader::kDeviceModeEnterprise,
+ device_policy_proto);
+
+ int value = -1;
+ ASSERT_TRUE(device_policy_.GetRollbackAllowedMilestones(&value));
+ EXPECT_EQ(3, value);
+}
+
+// RollbackAllowedMilestones is set to a valid value, using AD.
+TEST_F(DevicePolicyImplTest, GetRollbackAllowedMilestones_SetAD) {
+ em::ChromeDeviceSettingsProto device_policy_proto;
+ em::AutoUpdateSettingsProto* auto_update_settings =
+ device_policy_proto.mutable_auto_update_settings();
+ auto_update_settings->set_rollback_allowed_milestones(3);
+ InitializePolicy(InstallAttributesReader::kDeviceModeEnterpriseAD,
+ device_policy_proto);
+ int value = -1;
+ ASSERT_TRUE(device_policy_.GetRollbackAllowedMilestones(&value));
+ EXPECT_EQ(3, value);
+}
+
+// RollbackAllowedMilestones is set to a valid value, but it's not an enterprise
+// device.
+TEST_F(DevicePolicyImplTest, GetRollbackAllowedMilestones_SetConsumer) {
+ em::ChromeDeviceSettingsProto device_policy_proto;
+ em::AutoUpdateSettingsProto* auto_update_settings =
+ device_policy_proto.mutable_auto_update_settings();
+ auto_update_settings->set_rollback_allowed_milestones(3);
+ InitializePolicy(InstallAttributesReader::kDeviceModeConsumer,
+ device_policy_proto);
+
+ int value = -1;
+ ASSERT_FALSE(device_policy_.GetRollbackAllowedMilestones(&value));
+}
+
+// RollbackAllowedMilestones is set to an invalid value.
+TEST_F(DevicePolicyImplTest, GetRollbackAllowedMilestones_SetTooLarge) {
+ em::ChromeDeviceSettingsProto device_policy_proto;
+ em::AutoUpdateSettingsProto* auto_update_settings =
+ device_policy_proto.mutable_auto_update_settings();
+ auto_update_settings->set_rollback_allowed_milestones(10);
+ InitializePolicy(InstallAttributesReader::kDeviceModeEnterprise,
+ device_policy_proto);
+
+ int value = -1;
+ ASSERT_TRUE(device_policy_.GetRollbackAllowedMilestones(&value));
+ EXPECT_EQ(4, value);
+}
+
+// RollbackAllowedMilestones is set to an invalid value.
+TEST_F(DevicePolicyImplTest, GetRollbackAllowedMilestones_SetTooSmall) {
+ em::ChromeDeviceSettingsProto device_policy_proto;
+ em::AutoUpdateSettingsProto* auto_update_settings =
+ device_policy_proto.mutable_auto_update_settings();
+ auto_update_settings->set_rollback_allowed_milestones(-1);
+ InitializePolicy(InstallAttributesReader::kDeviceModeEnterprise,
+ device_policy_proto);
+
+ int value = -1;
+ ASSERT_TRUE(device_policy_.GetRollbackAllowedMilestones(&value));
+ EXPECT_EQ(0, value);
+}
+
+// Update staging schedule has no values
+TEST_F(DevicePolicyImplTest, GetDeviceUpdateStagingSchedule_NoValues) {
+ em::ChromeDeviceSettingsProto device_policy_proto;
+ em::AutoUpdateSettingsProto *auto_update_settings =
+ device_policy_proto.mutable_auto_update_settings();
+ auto_update_settings->set_staging_schedule("[]");
+ InitializePolicy(InstallAttributesReader::kDeviceModeEnterprise,
+ device_policy_proto);
+
+ std::vector<DayPercentagePair> staging_schedule;
+ ASSERT_TRUE(device_policy_.GetDeviceUpdateStagingSchedule(&staging_schedule));
+ EXPECT_EQ(0, staging_schedule.size());
+}
+
+// Update staging schedule has valid values
+TEST_F(DevicePolicyImplTest, GetDeviceUpdateStagingSchedule_Valid) {
+ em::ChromeDeviceSettingsProto device_policy_proto;
+ em::AutoUpdateSettingsProto *auto_update_settings =
+ device_policy_proto.mutable_auto_update_settings();
+ auto_update_settings->set_staging_schedule(
+ "[{\"days\": 4, \"percentage\": 40}, {\"days\": 10, \"percentage\": "
+ "100}]");
+ InitializePolicy(InstallAttributesReader::kDeviceModeEnterprise,
+ device_policy_proto);
+
+ std::vector<DayPercentagePair> staging_schedule;
+ ASSERT_TRUE(device_policy_.GetDeviceUpdateStagingSchedule(&staging_schedule));
+ EXPECT_THAT(staging_schedule, ElementsAre(DayPercentagePair{4, 40},
+ DayPercentagePair{10, 100}));
+}
+
+// Update staging schedule has valid values, set using AD.
+TEST_F(DevicePolicyImplTest, GetDeviceUpdateStagingSchedule_Valid_AD) {
+ em::ChromeDeviceSettingsProto device_policy_proto;
+ em::AutoUpdateSettingsProto *auto_update_settings =
+ device_policy_proto.mutable_auto_update_settings();
+ auto_update_settings->set_staging_schedule(
+ "[{\"days\": 4, \"percentage\": 40}, {\"days\": 10, \"percentage\": "
+ "100}]");
+ InitializePolicy(InstallAttributesReader::kDeviceModeEnterpriseAD,
+ device_policy_proto);
+
+ std::vector<DayPercentagePair> staging_schedule;
+ ASSERT_TRUE(device_policy_.GetDeviceUpdateStagingSchedule(&staging_schedule));
+ EXPECT_THAT(staging_schedule, ElementsAre(DayPercentagePair{4, 40},
+ DayPercentagePair{10, 100}));
+}
+
+// Update staging schedule has values with values set larger than the max
+// allowed days/percentage and smaller than the min allowed days/percentage.
+TEST_F(DevicePolicyImplTest,
+ GetDeviceUpdateStagingSchedule_SetOutsideAllowable) {
+ em::ChromeDeviceSettingsProto device_policy_proto;
+ em::AutoUpdateSettingsProto *auto_update_settings =
+ device_policy_proto.mutable_auto_update_settings();
+ auto_update_settings->set_staging_schedule(
+ "[{\"days\": -1, \"percentage\": -10}, {\"days\": 30, \"percentage\": "
+ "110}]");
+ InitializePolicy(InstallAttributesReader::kDeviceModeEnterprise,
+ device_policy_proto);
+
+ std::vector<DayPercentagePair> staging_schedule;
+ ASSERT_TRUE(device_policy_.GetDeviceUpdateStagingSchedule(&staging_schedule));
+ EXPECT_THAT(staging_schedule, ElementsAre(DayPercentagePair{1, 0},
+ DayPercentagePair{28, 100}));
+}
+
+} // namespace policy
diff --git a/policy/tests/libpolicy_unittest.cc b/policy/tests/libpolicy_unittest.cc
index bd2b49a..aaf497c 100644
--- a/policy/tests/libpolicy_unittest.cc
+++ b/policy/tests/libpolicy_unittest.cc
@@ -4,6 +4,9 @@
#include "policy/libpolicy.h"
+#include <memory>
+#include <utility>
+
#include <openssl/err.h>
#include <openssl/ssl.h>
@@ -11,6 +14,8 @@
#include <base/logging.h>
#include <gtest/gtest.h>
+#include "bindings/chrome_device_policy.pb.h"
+#include "install_attributes/mock_install_attributes_reader.h"
#include "policy/device_policy_impl.h"
namespace policy {
@@ -18,6 +23,7 @@ namespace policy {
static const char kPolicyFileAllSet[] = "policy/tests/whitelist/policy_all";
static const char kPolicyFileNoneSet[] = "policy/tests/whitelist/policy_none";
static const char kKeyFile[] = "policy/tests/whitelist/owner.key";
+static const char kNonExistingFile[] = "file-does-not-exist";
// Creates the DevicePolicyImpl with given parameters for test.
std::unique_ptr<DevicePolicyImpl> CreateDevicePolicyImpl(
@@ -40,10 +46,11 @@ std::unique_ptr<DevicePolicyImpl> CreateDevicePolicyImpl(
TEST(PolicyTest, DevicePolicyAllSetTest) {
base::FilePath policy_file(kPolicyFileAllSet);
base::FilePath key_file(kKeyFile);
- PolicyProvider provider(
- CreateDevicePolicyImpl(std::make_unique<MockInstallAttributesReader>(
- cryptohome::SerializedInstallAttributes()),
- policy_file, key_file, false));
+ PolicyProvider provider;
+ provider.SetDevicePolicyForTesting(CreateDevicePolicyImpl(
+ std::make_unique<MockInstallAttributesReader>(
+ InstallAttributesReader::kDeviceModeEnterprise, true),
+ policy_file, key_file, false));
provider.Reload();
// Ensure we successfully loaded the device policy file.
@@ -54,111 +61,143 @@ TEST(PolicyTest, DevicePolicyAllSetTest) {
// Check that we can read out all fields of the sample protobuf.
int int_value = -1;
ASSERT_TRUE(policy.GetPolicyRefreshRate(&int_value));
- ASSERT_EQ(100, int_value);
+ EXPECT_EQ(100, int_value);
std::vector<std::string> list_value;
ASSERT_TRUE(policy.GetUserWhitelist(&list_value));
ASSERT_EQ(3, list_value.size());
- ASSERT_EQ("me@here.com", list_value[0]);
- ASSERT_EQ("you@there.com", list_value[1]);
- ASSERT_EQ("*@monsters.com", list_value[2]);
+ EXPECT_EQ("me@here.com", list_value[0]);
+ EXPECT_EQ("you@there.com", list_value[1]);
+ EXPECT_EQ("*@monsters.com", list_value[2]);
bool bool_value = true;
ASSERT_TRUE(policy.GetGuestModeEnabled(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
bool_value = true;
ASSERT_TRUE(policy.GetCameraEnabled(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
bool_value = true;
ASSERT_TRUE(policy.GetShowUserNames(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
bool_value = true;
ASSERT_TRUE(policy.GetDataRoamingEnabled(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
bool_value = true;
ASSERT_TRUE(policy.GetAllowNewUsers(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
bool_value = true;
ASSERT_TRUE(policy.GetMetricsEnabled(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
bool_value = true;
ASSERT_TRUE(policy.GetReportVersionInfo(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
bool_value = true;
ASSERT_TRUE(policy.GetReportActivityTimes(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
bool_value = true;
ASSERT_TRUE(policy.GetReportBootMode(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
bool_value = true;
ASSERT_TRUE(policy.GetEphemeralUsersEnabled(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
std::string string_value;
ASSERT_TRUE(policy.GetReleaseChannel(&string_value));
- ASSERT_EQ("stable-channel", string_value);
+ EXPECT_EQ("stable-channel", string_value);
bool_value = false;
ASSERT_TRUE(policy.GetReleaseChannelDelegated(&bool_value));
- ASSERT_TRUE(bool_value);
+ EXPECT_TRUE(bool_value);
bool_value = true;
ASSERT_TRUE(policy.GetUpdateDisabled(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
int64_t int64_value = -1LL;
ASSERT_TRUE(policy.GetScatterFactorInSeconds(&int64_value));
- ASSERT_EQ(17LL, int64_value);
+ EXPECT_EQ(17LL, int64_value);
ASSERT_TRUE(policy.GetTargetVersionPrefix(&string_value));
- ASSERT_EQ("42.0.", string_value);
+ EXPECT_EQ("42.0.", string_value);
+
+ int_value = -1;
+ ASSERT_TRUE(policy.GetRollbackToTargetVersion(&int_value));
+ EXPECT_EQ(enterprise_management::AutoUpdateSettingsProto::
+ ROLLBACK_WITH_FULL_POWERWASH,
+ int_value);
+
+ int_value = -1;
+ ASSERT_TRUE(policy.GetRollbackAllowedMilestones(&int_value));
+ EXPECT_EQ(3, int_value);
std::set<std::string> types;
ASSERT_TRUE(policy.GetAllowedConnectionTypesForUpdate(&types));
- ASSERT_TRUE(types.end() != types.find("ethernet"));
- ASSERT_TRUE(types.end() != types.find("wifi"));
- ASSERT_EQ(2, types.size());
+ EXPECT_TRUE(types.end() != types.find("ethernet"));
+ EXPECT_TRUE(types.end() != types.find("wifi"));
+ EXPECT_EQ(2, types.size());
ASSERT_TRUE(policy.GetOpenNetworkConfiguration(&string_value));
- ASSERT_EQ("{}", string_value);
+ EXPECT_EQ("{}", string_value);
ASSERT_TRUE(policy.GetOwner(&string_value));
- ASSERT_EQ("", string_value);
+ EXPECT_EQ("", string_value);
bool_value = true;
ASSERT_TRUE(policy.GetHttpDownloadsEnabled(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
bool_value = true;
ASSERT_TRUE(policy.GetAuP2PEnabled(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
bool_value = true;
ASSERT_TRUE(policy.GetAllowKioskAppControlChromeVersion(&bool_value));
- ASSERT_FALSE(bool_value);
+ EXPECT_FALSE(bool_value);
std::vector<DevicePolicy::UsbDeviceId> list_device;
ASSERT_TRUE(policy.GetUsbDetachableWhitelist(&list_device));
- ASSERT_EQ(2, list_device.size());
- ASSERT_EQ(0x413c, list_device[0].vendor_id);
- ASSERT_EQ(0x2105, list_device[0].product_id);
- ASSERT_EQ(0x0403, list_device[1].vendor_id);
- ASSERT_EQ(0x6001, list_device[1].product_id);
+ EXPECT_EQ(2, list_device.size());
+ EXPECT_EQ(0x413c, list_device[0].vendor_id);
+ EXPECT_EQ(0x2105, list_device[0].product_id);
+ EXPECT_EQ(0x0403, list_device[1].vendor_id);
+ EXPECT_EQ(0x6001, list_device[1].product_id);
+
+ ASSERT_TRUE(policy.GetAutoLaunchedKioskAppId(&string_value));
+ EXPECT_EQ("my_kiosk_app", string_value);
+
+ int_value = -1;
+ ASSERT_TRUE(policy.GetSecondFactorAuthenticationMode(&int_value));
+ EXPECT_EQ(2, int_value);
+
+ std::vector<DevicePolicy::WeeklyTimeInterval> intervals;
+ ASSERT_TRUE(policy.GetDisallowedTimeIntervals(&intervals));
+ ASSERT_EQ(2, intervals.size());
+ EXPECT_EQ(4, intervals[0].start_day_of_week);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(30) + base::TimeDelta::FromHours(12),
+ intervals[0].start_time);
+ EXPECT_EQ(6, intervals[0].end_day_of_week);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(15) + base::TimeDelta::FromHours(3),
+ intervals[0].end_time);
+ EXPECT_EQ(1, intervals[1].start_day_of_week);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(10) + base::TimeDelta::FromHours(20),
+ intervals[1].start_time);
+ EXPECT_EQ(3, intervals[1].end_day_of_week);
+ EXPECT_EQ(base::TimeDelta::FromMinutes(20), intervals[1].end_time);
ASSERT_TRUE(policy.GetAutoLaunchedKioskAppId(&string_value));
ASSERT_EQ("my_kiosk_app", string_value);
// Reloading the protobuf should succeed.
- ASSERT_TRUE(provider.Reload());
+ EXPECT_TRUE(provider.Reload());
}
// Test that a policy file can be verified and parsed correctly. The file
@@ -167,10 +206,11 @@ TEST(PolicyTest, DevicePolicyNoneSetTest) {
base::FilePath policy_file(kPolicyFileNoneSet);
base::FilePath key_file(kKeyFile);
- PolicyProvider provider(
- CreateDevicePolicyImpl(std::make_unique<MockInstallAttributesReader>(
- cryptohome::SerializedInstallAttributes()),
- policy_file, key_file, false));
+ PolicyProvider provider;
+ provider.SetDevicePolicyForTesting(CreateDevicePolicyImpl(
+ std::make_unique<MockInstallAttributesReader>(
+ InstallAttributesReader::kDeviceModeEnterprise, true),
+ policy_file, key_file, false));
provider.Reload();
// Ensure we successfully loaded the device policy file.
@@ -185,45 +225,136 @@ TEST(PolicyTest, DevicePolicyNoneSetTest) {
bool bool_value;
std::string string_value;
std::vector<DevicePolicy::UsbDeviceId> list_device;
-
- ASSERT_FALSE(policy.GetPolicyRefreshRate(&int_value));
- ASSERT_FALSE(policy.GetUserWhitelist(&list_value));
- ASSERT_FALSE(policy.GetGuestModeEnabled(&bool_value));
- ASSERT_FALSE(policy.GetCameraEnabled(&bool_value));
- ASSERT_FALSE(policy.GetShowUserNames(&bool_value));
- ASSERT_FALSE(policy.GetDataRoamingEnabled(&bool_value));
- ASSERT_FALSE(policy.GetAllowNewUsers(&bool_value));
- ASSERT_FALSE(policy.GetMetricsEnabled(&bool_value));
- ASSERT_FALSE(policy.GetReportVersionInfo(&bool_value));
- ASSERT_FALSE(policy.GetReportActivityTimes(&bool_value));
- ASSERT_FALSE(policy.GetReportBootMode(&bool_value));
- ASSERT_FALSE(policy.GetEphemeralUsersEnabled(&bool_value));
- ASSERT_FALSE(policy.GetReleaseChannel(&string_value));
- ASSERT_FALSE(policy.GetUpdateDisabled(&bool_value));
- ASSERT_FALSE(policy.GetTargetVersionPrefix(&string_value));
- ASSERT_FALSE(policy.GetScatterFactorInSeconds(&int64_value));
- ASSERT_FALSE(policy.GetOpenNetworkConfiguration(&string_value));
- ASSERT_FALSE(policy.GetHttpDownloadsEnabled(&bool_value));
- ASSERT_FALSE(policy.GetAuP2PEnabled(&bool_value));
- ASSERT_FALSE(policy.GetAllowKioskAppControlChromeVersion(&bool_value));
- ASSERT_FALSE(policy.GetUsbDetachableWhitelist(&list_device));
+ std::vector<DevicePolicy::WeeklyTimeInterval> intervals;
+
+ EXPECT_FALSE(policy.GetPolicyRefreshRate(&int_value));
+ EXPECT_FALSE(policy.GetUserWhitelist(&list_value));
+ EXPECT_FALSE(policy.GetGuestModeEnabled(&bool_value));
+ EXPECT_FALSE(policy.GetCameraEnabled(&bool_value));
+ EXPECT_FALSE(policy.GetShowUserNames(&bool_value));
+ EXPECT_FALSE(policy.GetDataRoamingEnabled(&bool_value));
+ EXPECT_FALSE(policy.GetAllowNewUsers(&bool_value));
+ EXPECT_FALSE(policy.GetMetricsEnabled(&bool_value));
+ EXPECT_FALSE(policy.GetReportVersionInfo(&bool_value));
+ EXPECT_FALSE(policy.GetReportActivityTimes(&bool_value));
+ EXPECT_FALSE(policy.GetReportBootMode(&bool_value));
+ EXPECT_FALSE(policy.GetEphemeralUsersEnabled(&bool_value));
+ EXPECT_FALSE(policy.GetReleaseChannel(&string_value));
+ EXPECT_FALSE(policy.GetUpdateDisabled(&bool_value));
+ EXPECT_FALSE(policy.GetTargetVersionPrefix(&string_value));
+ EXPECT_FALSE(policy.GetRollbackToTargetVersion(&int_value));
+ // RollbackAllowedMilestones has the default value of 0 for enterprise
+ // devices.
+ ASSERT_TRUE(policy.GetRollbackAllowedMilestones(&int_value));
+ EXPECT_EQ(0, int_value);
+ EXPECT_FALSE(policy.GetScatterFactorInSeconds(&int64_value));
+ EXPECT_FALSE(policy.GetOpenNetworkConfiguration(&string_value));
+ EXPECT_FALSE(policy.GetHttpDownloadsEnabled(&bool_value));
+ EXPECT_FALSE(policy.GetAuP2PEnabled(&bool_value));
+ EXPECT_FALSE(policy.GetAllowKioskAppControlChromeVersion(&bool_value));
+ EXPECT_FALSE(policy.GetUsbDetachableWhitelist(&list_device));
+ EXPECT_FALSE(policy.GetSecondFactorAuthenticationMode(&int_value));
+ EXPECT_FALSE(policy.GetDisallowedTimeIntervals(&intervals));
}
// Verify that the library will correctly recognize and signal missing files.
TEST(PolicyTest, DevicePolicyFailure) {
LOG(INFO) << "Errors expected.";
// Try loading non-existing protobuf should fail.
- base::FilePath non_existing("this_file_is_doof");
- PolicyProvider provider(
+ base::FilePath policy_file(kNonExistingFile);
+ base::FilePath key_file(kNonExistingFile);
+ PolicyProvider provider;
+ provider.SetDevicePolicyForTesting(
CreateDevicePolicyImpl(std::make_unique<MockInstallAttributesReader>(
cryptohome::SerializedInstallAttributes()),
- non_existing,
- non_existing,
- true));
+ policy_file, key_file, true));
// Even after reload the policy should still be not loaded.
ASSERT_FALSE(provider.Reload());
- ASSERT_FALSE(provider.device_policy_is_loaded());
+ EXPECT_FALSE(provider.device_policy_is_loaded());
+}
+
+// Verify that signature verification is waived for a device in enterprise_ad
+// mode.
+TEST(PolicyTest, SkipSignatureForEnterpriseAD) {
+ base::FilePath policy_file(kPolicyFileAllSet);
+ base::FilePath key_file(kNonExistingFile);
+ PolicyProvider provider;
+ provider.SetDevicePolicyForTesting(CreateDevicePolicyImpl(
+ std::make_unique<MockInstallAttributesReader>(
+ InstallAttributesReader::kDeviceModeEnterpriseAD, true),
+ policy_file, key_file, false));
+ provider.Reload();
+
+ // Ensure we successfully loaded the device policy file.
+ EXPECT_TRUE(provider.device_policy_is_loaded());
+}
+
+// Ensure that signature verification is enforced for a device in vanilla
+// enterprise mode.
+TEST(PolicyTest, DontSkipSignatureForEnterprise) {
+ base::FilePath policy_file(kPolicyFileAllSet);
+ base::FilePath key_file(kNonExistingFile);
+
+ PolicyProvider provider;
+ provider.SetDevicePolicyForTesting(CreateDevicePolicyImpl(
+ std::make_unique<MockInstallAttributesReader>(
+ InstallAttributesReader::kDeviceModeEnterprise, true),
+ policy_file, key_file, false));
+ provider.Reload();
+
+ // Ensure that unverifed policy is not loaded.
+ EXPECT_FALSE(provider.device_policy_is_loaded());
+}
+
+// Ensure that signature verification is enforced for a device in consumer mode.
+TEST(PolicyTest, DontSkipSignatureForConsumer) {
+ base::FilePath policy_file(kPolicyFileAllSet);
+ base::FilePath key_file(kNonExistingFile);
+ cryptohome::SerializedInstallAttributes install_attributes;
+
+ PolicyProvider provider;
+ provider.SetDevicePolicyForTesting(CreateDevicePolicyImpl(
+ std::make_unique<MockInstallAttributesReader>(install_attributes),
+ policy_file, key_file, false));
+ provider.Reload();
+
+ // Ensure that unverifed policy is not loaded.
+ EXPECT_FALSE(provider.device_policy_is_loaded());
+}
+
+// Checks return value of IsConsumerDevice when it's a still in OOBE.
+TEST(PolicyTest, IsConsumerDeviceOobe) {
+ PolicyProvider provider;
+ provider.SetInstallAttributesReaderForTesting(
+ std::make_unique<MockInstallAttributesReader>("", false));
+ EXPECT_FALSE(provider.IsConsumerDevice());
+}
+
+// Checks return value of IsConsumerDevice when it's a consumer device.
+TEST(PolicyTest, IsConsumerDeviceConsumer) {
+ PolicyProvider provider;
+ provider.SetInstallAttributesReaderForTesting(
+ std::make_unique<MockInstallAttributesReader>("", true));
+ EXPECT_TRUE(provider.IsConsumerDevice());
+}
+
+// Checks return value of IsConsumerDevice when it's an enterprise device.
+TEST(PolicyTest, IsConsumerDeviceEnterprise) {
+ PolicyProvider provider;
+ provider.SetInstallAttributesReaderForTesting(
+ std::make_unique<MockInstallAttributesReader>(
+ InstallAttributesReader::kDeviceModeEnterprise, true));
+ EXPECT_FALSE(provider.IsConsumerDevice());
+}
+
+// Checks return value of IsConsumerDevice when it's an enterprise AD device.
+TEST(PolicyTest, IsConsumerDeviceEnterpriseAd) {
+ PolicyProvider provider;
+ provider.SetInstallAttributesReaderForTesting(
+ std::make_unique<MockInstallAttributesReader>(
+ InstallAttributesReader::kDeviceModeEnterpriseAD, true));
+ EXPECT_FALSE(provider.IsConsumerDevice());
}
} // namespace policy
diff --git a/policy/tests/policy_util_unittest.cc b/policy/tests/policy_util_unittest.cc
index 74032d4..f26622f 100644
--- a/policy/tests/policy_util_unittest.cc
+++ b/policy/tests/policy_util_unittest.cc
@@ -20,9 +20,9 @@ TEST(DevicePolicyUtilTest, LoadPolicyFromPath) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- base::FilePath invalid_policy_data_path(temp_dir.path().Append("policy"));
- base::FilePath inexistent_file(temp_dir.path().Append("policy.1"));
- base::FilePath good_policy_data_path(temp_dir.path().Append("policy.2"));
+ base::FilePath invalid_policy_data_path(temp_dir.GetPath().Append("policy"));
+ base::FilePath inexistent_file(temp_dir.GetPath().Append("policy.1"));
+ base::FilePath good_policy_data_path(temp_dir.GetPath().Append("policy.2"));
// Create the file with invalid data.
std::string data = "invalid data";
diff --git a/policy/tests/resilient_policy_util_unittest.cc b/policy/tests/resilient_policy_util_unittest.cc
index e45ab34..0963b08 100644
--- a/policy/tests/resilient_policy_util_unittest.cc
+++ b/policy/tests/resilient_policy_util_unittest.cc
@@ -31,11 +31,11 @@ TEST(DevicePolicyUtilTest, GetSortedResilientPolicyFilePaths) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
- base::FilePath file0(temp_dir.path().Append("policy"));
- base::FilePath file1(temp_dir.path().Append("policy.12"));
- base::FilePath file2(temp_dir.path().Append("policy.2"));
- base::FilePath file3(temp_dir.path().Append("policy.30"));
- base::FilePath invalid(temp_dir.path().Append("policy_4"));
+ base::FilePath file0(temp_dir.GetPath().Append("policy"));
+ base::FilePath file1(temp_dir.GetPath().Append("policy.12"));
+ base::FilePath file2(temp_dir.GetPath().Append("policy.2"));
+ base::FilePath file3(temp_dir.GetPath().Append("policy.30"));
+ base::FilePath invalid(temp_dir.GetPath().Append("policy_4"));
CreateFile(file0);
CreateFile(file1);
@@ -43,7 +43,7 @@ TEST(DevicePolicyUtilTest, GetSortedResilientPolicyFilePaths) {
CreateFile(file3);
const base::FilePath test_file_path(
- temp_dir.path().Append(kDefaultResilientPolicyFilePath));
+ temp_dir.GetPath().Append(kDefaultResilientPolicyFilePath));
std::map<int, base::FilePath> sorted_file_paths =
GetSortedResilientPolicyFilePaths(test_file_path);
diff --git a/policy/tests/whitelist/policy_all b/policy/tests/whitelist/policy_all
index ff197cd..c0dfaaf 100644
--- a/policy/tests/whitelist/policy_all
+++ b/policy/tests/whitelist/policy_all
Binary files differ