| Index: chromeos/network/policy_applicator.cc
|
| diff --git a/chromeos/network/managed_network_configuration_handler_impl.cc b/chromeos/network/policy_applicator.cc
|
| similarity index 20%
|
| copy from chromeos/network/managed_network_configuration_handler_impl.cc
|
| copy to chromeos/network/policy_applicator.cc
|
| index 6ecc7ec114c2c5bfb781e3df4c8cc9b296021dac..33fa703283a46591e338bdc94659b948e7c49363 100644
|
| --- a/chromeos/network/managed_network_configuration_handler_impl.cc
|
| +++ b/chromeos/network/policy_applicator.cc
|
| @@ -2,39 +2,22 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| -#include "chromeos/network/managed_network_configuration_handler_impl.h"
|
| +#include "chromeos/network/policy_applicator.h"
|
|
|
| #include <utility>
|
| -#include <vector>
|
|
|
| #include "base/bind.h"
|
| -#include "base/guid.h"
|
| #include "base/location.h"
|
| #include "base/logging.h"
|
| -#include "base/memory/ref_counted.h"
|
| #include "base/stl_util.h"
|
| -#include "base/strings/string_util.h"
|
| #include "base/values.h"
|
| -#include "chromeos/dbus/dbus_method_call_status.h"
|
| #include "chromeos/dbus/dbus_thread_manager.h"
|
| -#include "chromeos/dbus/shill_manager_client.h"
|
| #include "chromeos/dbus/shill_profile_client.h"
|
| -#include "chromeos/dbus/shill_service_client.h"
|
| -#include "chromeos/network/network_configuration_handler.h"
|
| -#include "chromeos/network/network_event_log.h"
|
| -#include "chromeos/network/network_policy_observer.h"
|
| -#include "chromeos/network/network_profile.h"
|
| -#include "chromeos/network/network_profile_handler.h"
|
| -#include "chromeos/network/network_state.h"
|
| -#include "chromeos/network/network_state_handler.h"
|
| #include "chromeos/network/network_ui_data.h"
|
| #include "chromeos/network/onc/onc_constants.h"
|
| -#include "chromeos/network/onc/onc_merger.h"
|
| -#include "chromeos/network/onc/onc_normalizer.h"
|
| #include "chromeos/network/onc/onc_signature.h"
|
| #include "chromeos/network/onc/onc_translator.h"
|
| -#include "chromeos/network/onc/onc_utils.h"
|
| -#include "chromeos/network/onc/onc_validator.h"
|
| +#include "chromeos/network/policy_util.h"
|
| #include "chromeos/network/shill_property_util.h"
|
| #include "dbus/object_path.h"
|
| #include "third_party/cros_system_api/dbus/service_constants.h"
|
| @@ -43,765 +26,27 @@ namespace chromeos {
|
|
|
| namespace {
|
|
|
| -// These are error strings used for error callbacks. None of these error
|
| -// messages are user-facing: they should only appear in logs.
|
| -const char kInvalidUserSettingsMessage[] = "User settings are invalid.";
|
| -const char kInvalidUserSettings[] = "Error.InvalidUserSettings";
|
| -const char kNetworkAlreadyConfiguredMessage[] =
|
| - "Network is already configured.";
|
| -const char kNetworkAlreadyConfigured[] = "Error.NetworkAlreadyConfigured";
|
| -const char kPoliciesNotInitializedMessage[] = "Policies not initialized.";
|
| -const char kPoliciesNotInitialized[] = "Error.PoliciesNotInitialized";
|
| -const char kProfileNotInitializedMessage[] = "Profile not initialized.";
|
| -const char kProfileNotInitialized[] = "Error.ProflieNotInitialized";
|
| -const char kSetOnUnconfiguredNetworkMessage[] =
|
| - "Unable to modify properties of an unconfigured network.";
|
| -const char kSetOnUnconfiguredNetwork[] = "Error.SetCalledOnUnconfiguredNetwork";
|
| -const char kUnknownProfilePathMessage[] = "Profile path is unknown.";
|
| -const char kUnknownProfilePath[] = "Error.UnknownProfilePath";
|
| -const char kUnknownServicePathMessage[] = "Service path is unknown.";
|
| -const char kUnknownServicePath[] = "Error.UnknownServicePath";
|
| -
|
| -// This fake credential contains a random postfix which is extremly unlikely to
|
| -// be used by any user.
|
| -const char kFakeCredential[] = "FAKE_CREDENTIAL_VPaJDV9x";
|
| -
|
| -std::string ToDebugString(onc::ONCSource source,
|
| - const std::string& userhash) {
|
| - return source == onc::ONC_SOURCE_USER_POLICY ?
|
| - ("user policy of " + userhash) : "device policy";
|
| -}
|
| -
|
| -void RunErrorCallback(const std::string& service_path,
|
| - const std::string& error_name,
|
| - const std::string& error_message,
|
| - const network_handler::ErrorCallback& error_callback) {
|
| - NET_LOG_ERROR(error_name, error_message);
|
| - error_callback.Run(
|
| - error_name,
|
| - make_scoped_ptr(
|
| - network_handler::CreateErrorData(service_path,
|
| - error_name,
|
| - error_message)));
|
| -}
|
| -
|
| -void LogErrorWithDict(const tracked_objects::Location& from_where,
|
| - const std::string& error_name,
|
| - scoped_ptr<base::DictionaryValue> error_data) {
|
| - LOG(ERROR) << from_where.ToString() << ": " << error_name;
|
| -}
|
| -
|
| void LogErrorMessage(const tracked_objects::Location& from_where,
|
| const std::string& error_name,
|
| const std::string& error_message) {
|
| LOG(ERROR) << from_where.ToString() << ": " << error_message;
|
| }
|
|
|
| -// Removes all kFakeCredential values from sensitive fields (determined by
|
| -// onc::FieldIsCredential) of |onc_object|.
|
| -void RemoveFakeCredentials(
|
| - const onc::OncValueSignature& signature,
|
| - base::DictionaryValue* onc_object) {
|
| - base::DictionaryValue::Iterator it(*onc_object);
|
| - while (!it.IsAtEnd()) {
|
| - base::Value* value = NULL;
|
| - std::string field_name = it.key();
|
| - // We need the non-const entry to remove nested values but DictionaryValue
|
| - // has no non-const iterator.
|
| - onc_object->GetWithoutPathExpansion(field_name, &value);
|
| - // Advance before delete.
|
| - it.Advance();
|
| -
|
| - // If |value| is a dictionary, recurse.
|
| - base::DictionaryValue* nested_object = NULL;
|
| - if (value->GetAsDictionary(&nested_object)) {
|
| - const onc::OncFieldSignature* field_signature =
|
| - onc::GetFieldSignature(signature, field_name);
|
| -
|
| - RemoveFakeCredentials(*field_signature->value_signature,
|
| - nested_object);
|
| - continue;
|
| - }
|
| -
|
| - // If |value| is a string, check if it is a fake credential.
|
| - std::string string_value;
|
| - if (value->GetAsString(&string_value) &&
|
| - onc::FieldIsCredential(signature, field_name)) {
|
| - if (string_value == kFakeCredential) {
|
| - // The value wasn't modified by the UI, thus we remove the field to keep
|
| - // the existing value that is stored in Shill.
|
| - onc_object->RemoveWithoutPathExpansion(field_name, NULL);
|
| - }
|
| - // Otherwise, the value is set and modified by the UI, thus we keep that
|
| - // value to overwrite whatever is stored in Shill.
|
| - }
|
| - }
|
| -}
|
| -
|
| -// Creates a Shill property dictionary from the given arguments. The resulting
|
| -// dictionary will be sent to Shill by the caller. Depending on the profile
|
| -// type, |policy| is interpreted as the user or device policy and |settings| as
|
| -// the user or shared settings. |policy| or |settings| can be NULL, but not
|
| -// both.
|
| -scoped_ptr<base::DictionaryValue> CreateShillConfiguration(
|
| - const NetworkProfile& profile,
|
| - const std::string& guid,
|
| - const base::DictionaryValue* policy,
|
| - const base::DictionaryValue* settings) {
|
| - scoped_ptr<base::DictionaryValue> effective;
|
| - onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
|
| - if (policy) {
|
| - if (profile.type() == NetworkProfile::TYPE_SHARED) {
|
| - effective = onc::MergeSettingsAndPoliciesToEffective(
|
| - NULL, // no user policy
|
| - policy, // device policy
|
| - NULL, // no user settings
|
| - settings); // shared settings
|
| - onc_source = onc::ONC_SOURCE_DEVICE_POLICY;
|
| - } else if (profile.type() == NetworkProfile::TYPE_USER) {
|
| - effective = onc::MergeSettingsAndPoliciesToEffective(
|
| - policy, // user policy
|
| - NULL, // no device policy
|
| - settings, // user settings
|
| - NULL); // no shared settings
|
| - onc_source = onc::ONC_SOURCE_USER_POLICY;
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| - } else if (settings) {
|
| - effective.reset(settings->DeepCopy());
|
| - // TODO(pneubeck): change to source ONC_SOURCE_USER
|
| - onc_source = onc::ONC_SOURCE_NONE;
|
| - } else {
|
| - NOTREACHED();
|
| - onc_source = onc::ONC_SOURCE_NONE;
|
| - }
|
| -
|
| - RemoveFakeCredentials(onc::kNetworkConfigurationSignature,
|
| - effective.get());
|
| -
|
| - effective->SetStringWithoutPathExpansion(onc::network_config::kGUID, guid);
|
| -
|
| - // Remove irrelevant fields.
|
| - onc::Normalizer normalizer(true /* remove recommended fields */);
|
| - effective = normalizer.NormalizeObject(&onc::kNetworkConfigurationSignature,
|
| - *effective);
|
| -
|
| - scoped_ptr<base::DictionaryValue> shill_dictionary(
|
| - onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature,
|
| - *effective));
|
| -
|
| - shill_dictionary->SetStringWithoutPathExpansion(flimflam::kProfileProperty,
|
| - profile.path);
|
| -
|
| - scoped_ptr<NetworkUIData> ui_data;
|
| - if (policy)
|
| - ui_data = NetworkUIData::CreateFromONC(onc_source, *policy);
|
| - else
|
| - ui_data.reset(new NetworkUIData());
|
| -
|
| - if (settings) {
|
| - // Shill doesn't know that sensitive data is contained in the UIData
|
| - // property and might write it into logs or other insecure places. Thus, we
|
| - // have to remove or mask credentials.
|
| - //
|
| - // Shill's GetProperties doesn't return credentials. Masking credentials
|
| - // instead of just removing them, allows remembering if a credential is set
|
| - // or not.
|
| - scoped_ptr<base::DictionaryValue> sanitized_settings(
|
| - onc::MaskCredentialsInOncObject(onc::kNetworkConfigurationSignature,
|
| - *settings,
|
| - kFakeCredential));
|
| - ui_data->set_user_settings(sanitized_settings.Pass());
|
| - }
|
| -
|
| - shill_property_util::SetUIData(*ui_data, shill_dictionary.get());
|
| -
|
| - VLOG(2) << "Created Shill properties: " << *shill_dictionary;
|
| -
|
| - return shill_dictionary.Pass();
|
| -}
|
| -
|
| -// Returns true if |policy| matches |actual_network|, which must be part of a
|
| -// ONC NetworkConfiguration. This should be the only such matching function
|
| -// within Chrome. Shill does such matching in several functions for network
|
| -// identification. For compatibility, we currently should stick to Shill's
|
| -// matching behavior.
|
| -bool IsPolicyMatching(const base::DictionaryValue& policy,
|
| - const base::DictionaryValue& actual_network) {
|
| - std::string policy_type;
|
| - policy.GetStringWithoutPathExpansion(onc::network_config::kType,
|
| - &policy_type);
|
| - std::string network_type;
|
| - actual_network.GetStringWithoutPathExpansion(onc::network_config::kType,
|
| - &network_type);
|
| - if (policy_type != network_type)
|
| - return false;
|
| -
|
| - if (network_type != onc::network_type::kWiFi)
|
| - return false;
|
| -
|
| - const base::DictionaryValue* policy_wifi = NULL;
|
| - policy.GetDictionaryWithoutPathExpansion(onc::network_config::kWiFi,
|
| - &policy_wifi);
|
| - const base::DictionaryValue* actual_wifi = NULL;
|
| - actual_network.GetDictionaryWithoutPathExpansion(onc::network_config::kWiFi,
|
| - &actual_wifi);
|
| - if (!policy_wifi || !actual_wifi)
|
| - return false;
|
| -
|
| - std::string policy_ssid;
|
| - policy_wifi->GetStringWithoutPathExpansion(onc::wifi::kSSID, &policy_ssid);
|
| - std::string actual_ssid;
|
| - actual_wifi->GetStringWithoutPathExpansion(onc::wifi::kSSID, &actual_ssid);
|
| - return (policy_ssid == actual_ssid);
|
| -}
|
| -
|
| -// Returns the policy from |policies| matching |actual_network|, if any exists.
|
| -// Returns NULL otherwise. |actual_network| must be part of a ONC
|
| -// NetworkConfiguration.
|
| -const base::DictionaryValue* FindMatchingPolicy(
|
| - const ManagedNetworkConfigurationHandlerImpl::GuidToPolicyMap& policies,
|
| - const base::DictionaryValue& actual_network) {
|
| - for (ManagedNetworkConfigurationHandlerImpl::GuidToPolicyMap::const_iterator
|
| - it = policies.begin();
|
| - it != policies.end(); ++it) {
|
| - if (IsPolicyMatching(*it->second, actual_network))
|
| - return it->second;
|
| - }
|
| - return NULL;
|
| -}
|
| -
|
| const base::DictionaryValue* GetByGUID(
|
| - const ManagedNetworkConfigurationHandlerImpl::GuidToPolicyMap& policies,
|
| + const PolicyApplicator::GuidToPolicyMap& policies,
|
| const std::string& guid) {
|
| - ManagedNetworkConfigurationHandlerImpl::GuidToPolicyMap::const_iterator it =
|
| - policies.find(guid);
|
| + PolicyApplicator::GuidToPolicyMap::const_iterator it = policies.find(guid);
|
| if (it == policies.end())
|
| return NULL;
|
| return it->second;
|
| }
|
|
|
| -void TranslatePropertiesToOncAndRunCallback(
|
| - const network_handler::DictionaryResultCallback& callback,
|
| - const std::string& service_path,
|
| - const base::DictionaryValue& shill_properties) {
|
| - scoped_ptr<base::DictionaryValue> onc_network(
|
| - onc::TranslateShillServiceToONCPart(
|
| - shill_properties,
|
| - &onc::kNetworkWithStateSignature));
|
| - callback.Run(service_path, *onc_network);
|
| -}
|
| -
|
| } // namespace
|
|
|
| -// This class compares (entry point is Run()) |modified_policies| with the
|
| -// existing entries in the provided Shill profile |profile|. It fetches all
|
| -// entries in parallel (GetProfilePropertiesCallback), compares each entry with
|
| -// the current policies (GetEntryCallback) and adds all missing policies
|
| -// (~PolicyApplicator).
|
| -class ManagedNetworkConfigurationHandlerImpl::PolicyApplicator
|
| - : public base::RefCounted<PolicyApplicator> {
|
| - public:
|
| - typedef ManagedNetworkConfigurationHandlerImpl::GuidToPolicyMap
|
| - GuidToPolicyMap;
|
| -
|
| - // |modified_policies| must not be NULL and will be empty afterwards.
|
| - PolicyApplicator(
|
| - base::WeakPtr<ManagedNetworkConfigurationHandlerImpl> handler,
|
| - const NetworkProfile& profile,
|
| - const GuidToPolicyMap& all_policies,
|
| - std::set<std::string>* modified_policies);
|
| -
|
| - void Run();
|
| -
|
| - private:
|
| - friend class base::RefCounted<PolicyApplicator>;
|
| -
|
| - // Called with the properties of the profile |profile_|. Requests the
|
| - // properties of each entry, which are processed by GetEntryCallback.
|
| - void GetProfilePropertiesCallback(
|
| - const base::DictionaryValue& profile_properties);
|
| -
|
| - // Called with the properties of the profile entry |entry|. Checks whether the
|
| - // entry was previously managed, whether a current policy applies and then
|
| - // either updates, deletes or not touches the entry.
|
| - void GetEntryCallback(const std::string& entry,
|
| - const base::DictionaryValue& entry_properties);
|
| -
|
| - // Sends Shill the command to delete profile entry |entry| from |profile_|.
|
| - void DeleteEntry(const std::string& entry);
|
| -
|
| - // Creates a Shill configuration from the given parameters and sends them to
|
| - // Shill. |user_settings| can be NULL if none exist.
|
| - void CreateAndWriteNewShillConfiguration(
|
| - const std::string& guid,
|
| - const base::DictionaryValue& policy,
|
| - const base::DictionaryValue* user_settings);
|
| -
|
| - // Called once all Profile entries are processed. Calls
|
| - // ApplyRemainingPolicies.
|
| - virtual ~PolicyApplicator();
|
| -
|
| - // Creates new entries for all remaining policies, i.e. for which no matching
|
| - // Profile entry was found.
|
| - void ApplyRemainingPolicies();
|
| -
|
| - std::set<std::string> remaining_policies_;
|
| - base::WeakPtr<ManagedNetworkConfigurationHandlerImpl> handler_;
|
| - NetworkProfile profile_;
|
| - GuidToPolicyMap all_policies_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(PolicyApplicator);
|
| -};
|
| -
|
| -void ManagedNetworkConfigurationHandlerImpl::AddObserver(
|
| - NetworkPolicyObserver* observer) {
|
| - observers_.AddObserver(observer);
|
| -}
|
| -
|
| -void ManagedNetworkConfigurationHandlerImpl::RemoveObserver(
|
| - NetworkPolicyObserver* observer) {
|
| - observers_.RemoveObserver(observer);
|
| -}
|
| -
|
| -void ManagedNetworkConfigurationHandlerImpl::GetManagedProperties(
|
| - const std::string& userhash,
|
| - const std::string& service_path,
|
| - const network_handler::DictionaryResultCallback& callback,
|
| - const network_handler::ErrorCallback& error_callback) {
|
| - if (!GetPoliciesForUser(userhash) || !GetPoliciesForUser(std::string())) {
|
| - RunErrorCallback(service_path,
|
| - kPoliciesNotInitialized,
|
| - kPoliciesNotInitializedMessage,
|
| - error_callback);
|
| - return;
|
| - }
|
| - network_configuration_handler_->GetProperties(
|
| - service_path,
|
| - base::Bind(
|
| - &ManagedNetworkConfigurationHandlerImpl::GetManagedPropertiesCallback,
|
| - weak_ptr_factory_.GetWeakPtr(),
|
| - callback,
|
| - error_callback),
|
| - error_callback);
|
| -}
|
| -
|
| -void ManagedNetworkConfigurationHandlerImpl::GetManagedPropertiesCallback(
|
| - const network_handler::DictionaryResultCallback& callback,
|
| - const network_handler::ErrorCallback& error_callback,
|
| - const std::string& service_path,
|
| - const base::DictionaryValue& shill_properties) {
|
| - std::string profile_path;
|
| - shill_properties.GetStringWithoutPathExpansion(flimflam::kProfileProperty,
|
| - &profile_path);
|
| - const NetworkProfile* profile =
|
| - network_profile_handler_->GetProfileForPath(profile_path);
|
| - if (!profile) {
|
| - LOG(ERROR) << "No or no known profile received for service "
|
| - << service_path << ".";
|
| - }
|
| -
|
| - scoped_ptr<NetworkUIData> ui_data =
|
| - shill_property_util::GetUIDataFromProperties(shill_properties);
|
| -
|
| - const base::DictionaryValue* user_settings = NULL;
|
| - const base::DictionaryValue* shared_settings = NULL;
|
| -
|
| - if (ui_data && profile) {
|
| - if (profile->type() == NetworkProfile::TYPE_SHARED)
|
| - shared_settings = ui_data->user_settings();
|
| - else if (profile->type() == NetworkProfile::TYPE_USER)
|
| - user_settings = ui_data->user_settings();
|
| - else
|
| - NOTREACHED();
|
| - } else if (profile) {
|
| - LOG(WARNING) << "Service " << service_path << " of profile "
|
| - << profile_path << " contains no or no valid UIData.";
|
| - // TODO(pneubeck): add a conversion of user configured entries of old
|
| - // ChromeOS versions. We will have to use a heuristic to determine which
|
| - // properties _might_ be user configured.
|
| - }
|
| -
|
| - scoped_ptr<base::DictionaryValue> active_settings(
|
| - onc::TranslateShillServiceToONCPart(
|
| - shill_properties,
|
| - &onc::kNetworkWithStateSignature));
|
| -
|
| - std::string guid;
|
| - active_settings->GetStringWithoutPathExpansion(onc::network_config::kGUID,
|
| - &guid);
|
| -
|
| - const base::DictionaryValue* user_policy = NULL;
|
| - const base::DictionaryValue* device_policy = NULL;
|
| - if (!guid.empty() && profile) {
|
| - const GuidToPolicyMap* policies = GetPoliciesForProfile(*profile);
|
| - if (!policies) {
|
| - RunErrorCallback(service_path,
|
| - kPoliciesNotInitialized,
|
| - kPoliciesNotInitializedMessage,
|
| - error_callback);
|
| - return;
|
| - }
|
| - const base::DictionaryValue* policy = GetByGUID(*policies, guid);
|
| - if (profile->type() == NetworkProfile::TYPE_SHARED)
|
| - device_policy = policy;
|
| - else if (profile->type() == NetworkProfile::TYPE_USER)
|
| - user_policy = policy;
|
| - else
|
| - NOTREACHED();
|
| - }
|
| -
|
| - // This call also removes credentials from policies.
|
| - scoped_ptr<base::DictionaryValue> augmented_properties =
|
| - onc::MergeSettingsAndPoliciesToAugmented(
|
| - onc::kNetworkConfigurationSignature,
|
| - user_policy,
|
| - device_policy,
|
| - user_settings,
|
| - shared_settings,
|
| - active_settings.get());
|
| - callback.Run(service_path, *augmented_properties);
|
| -}
|
| -
|
| -void ManagedNetworkConfigurationHandlerImpl::GetProperties(
|
| - const std::string& service_path,
|
| - const network_handler::DictionaryResultCallback& callback,
|
| - const network_handler::ErrorCallback& error_callback) const {
|
| - network_configuration_handler_->GetProperties(
|
| - service_path,
|
| - base::Bind(&TranslatePropertiesToOncAndRunCallback, callback),
|
| - error_callback);
|
| -}
|
| -
|
| -void ManagedNetworkConfigurationHandlerImpl::SetProperties(
|
| - const std::string& service_path,
|
| - const base::DictionaryValue& user_settings,
|
| - const base::Closure& callback,
|
| - const network_handler::ErrorCallback& error_callback) const {
|
| - const NetworkState* state =
|
| - network_state_handler_->GetNetworkState(service_path);
|
| -
|
| - if (!state) {
|
| - RunErrorCallback(service_path,
|
| - kUnknownServicePath,
|
| - kUnknownServicePathMessage,
|
| - error_callback);
|
| - return;
|
| - }
|
| -
|
| - std::string guid = state->guid();
|
| - if (guid.empty()) {
|
| - // TODO(pneubeck): create an initial configuration in this case. As for
|
| - // CreateConfiguration, user settings from older ChromeOS versions have to
|
| - // determined here.
|
| - RunErrorCallback(service_path,
|
| - kSetOnUnconfiguredNetwork,
|
| - kSetOnUnconfiguredNetworkMessage,
|
| - error_callback);
|
| - return;
|
| - }
|
| -
|
| - const std::string& profile_path = state->profile_path();
|
| - const NetworkProfile *profile =
|
| - network_profile_handler_->GetProfileForPath(profile_path);
|
| - if (!profile) {
|
| - RunErrorCallback(service_path,
|
| - kUnknownProfilePath,
|
| - kUnknownProfilePathMessage,
|
| - error_callback);
|
| - return;
|
| - }
|
| -
|
| - VLOG(2) << "SetProperties: Found GUID " << guid << " and profile "
|
| - << profile->ToDebugString();
|
| -
|
| - const GuidToPolicyMap* policies = GetPoliciesForProfile(*profile);
|
| - if (!policies) {
|
| - RunErrorCallback(service_path,
|
| - kPoliciesNotInitialized,
|
| - kPoliciesNotInitializedMessage,
|
| - error_callback);
|
| - return;
|
| - }
|
| -
|
| - // Validate the ONC dictionary. We are liberal and ignore unknown field
|
| - // names. User settings are only partial ONC, thus we ignore missing fields.
|
| - onc::Validator validator(false, // Ignore unknown fields.
|
| - false, // Ignore invalid recommended field names.
|
| - false, // Ignore missing fields.
|
| - false); // This ONC does not come from policy.
|
| -
|
| - onc::Validator::Result validation_result;
|
| - scoped_ptr<base::DictionaryValue> validated_user_settings =
|
| - validator.ValidateAndRepairObject(
|
| - &onc::kNetworkConfigurationSignature,
|
| - user_settings,
|
| - &validation_result);
|
| -
|
| - if (validation_result == onc::Validator::INVALID) {
|
| - RunErrorCallback(service_path,
|
| - kInvalidUserSettings,
|
| - kInvalidUserSettingsMessage,
|
| - error_callback);
|
| - return;
|
| - }
|
| - if (validation_result == onc::Validator::VALID_WITH_WARNINGS)
|
| - LOG(WARNING) << "Validation of ONC user settings produced warnings.";
|
| -
|
| - const base::DictionaryValue* policy = GetByGUID(*policies, guid);
|
| - VLOG(2) << "This configuration is " << (policy ? "" : "not ") << "managed.";
|
| -
|
| - scoped_ptr<base::DictionaryValue> shill_dictionary(CreateShillConfiguration(
|
| - *profile, guid, policy, validated_user_settings.get()));
|
| -
|
| - network_configuration_handler_->SetProperties(
|
| - service_path, *shill_dictionary, callback, error_callback);
|
| -}
|
| -
|
| -void ManagedNetworkConfigurationHandlerImpl::CreateConfiguration(
|
| - const std::string& userhash,
|
| - const base::DictionaryValue& properties,
|
| - const network_handler::StringResultCallback& callback,
|
| - const network_handler::ErrorCallback& error_callback) const {
|
| - const GuidToPolicyMap* policies = GetPoliciesForUser(userhash);
|
| - if (!policies) {
|
| - RunErrorCallback("",
|
| - kPoliciesNotInitialized,
|
| - kPoliciesNotInitializedMessage,
|
| - error_callback);
|
| - return;
|
| - }
|
| -
|
| - if (FindMatchingPolicy(*policies, properties)) {
|
| - RunErrorCallback("",
|
| - kNetworkAlreadyConfigured,
|
| - kNetworkAlreadyConfiguredMessage,
|
| - error_callback);
|
| - }
|
| -
|
| - const NetworkProfile* profile =
|
| - network_profile_handler_->GetProfileForUserhash(userhash);
|
| - if (!profile) {
|
| - RunErrorCallback("",
|
| - kProfileNotInitialized,
|
| - kProfileNotInitializedMessage,
|
| - error_callback);
|
| - }
|
| -
|
| - // TODO(pneubeck): In case of WiFi, check that no other configuration for the
|
| - // same {SSID, mode, security} exists. We don't support such multiple
|
| - // configurations, yet.
|
| -
|
| - // Generate a new GUID for this configuration. Ignore the maybe provided GUID
|
| - // in |properties| as it is not our own and from an untrusted source.
|
| - std::string guid = base::GenerateGUID();
|
| - scoped_ptr<base::DictionaryValue> shill_dictionary(
|
| - CreateShillConfiguration(*profile, guid, NULL /*no policy*/,
|
| - &properties));
|
| -
|
| - network_configuration_handler_->CreateConfiguration(
|
| - *shill_dictionary, callback, error_callback);
|
| -}
|
| -
|
| -void ManagedNetworkConfigurationHandlerImpl::RemoveConfiguration(
|
| - const std::string& service_path,
|
| - const base::Closure& callback,
|
| - const network_handler::ErrorCallback& error_callback) const {
|
| - network_configuration_handler_->RemoveConfiguration(
|
| - service_path, callback, error_callback);
|
| -}
|
| -
|
| -void ManagedNetworkConfigurationHandlerImpl::SetPolicy(
|
| - onc::ONCSource onc_source,
|
| - const std::string& userhash,
|
| - const base::ListValue& network_configs_onc) {
|
| - VLOG(1) << "Setting policies from " << ToDebugString(onc_source, userhash)
|
| - << ".";
|
| -
|
| - // |userhash| must be empty for device policies.
|
| - DCHECK(onc_source != chromeos::onc::ONC_SOURCE_DEVICE_POLICY ||
|
| - userhash.empty());
|
| - GuidToPolicyMap& policies = policies_by_user_[userhash];
|
| -
|
| - GuidToPolicyMap old_policies;
|
| - policies.swap(old_policies);
|
| -
|
| - // This stores all GUIDs of policies that have changed or are new.
|
| - std::set<std::string> modified_policies;
|
| -
|
| - for (base::ListValue::const_iterator it = network_configs_onc.begin();
|
| - it != network_configs_onc.end(); ++it) {
|
| - const base::DictionaryValue* network = NULL;
|
| - (*it)->GetAsDictionary(&network);
|
| - DCHECK(network);
|
| -
|
| - std::string guid;
|
| - network->GetStringWithoutPathExpansion(onc::network_config::kGUID, &guid);
|
| - DCHECK(!guid.empty());
|
| -
|
| - if (policies.count(guid) > 0) {
|
| - LOG(ERROR) << "ONC from " << ToDebugString(onc_source, userhash)
|
| - << " contains several entries for the same GUID "
|
| - << guid << ".";
|
| - delete policies[guid];
|
| - }
|
| - const base::DictionaryValue* new_entry = network->DeepCopy();
|
| - policies[guid] = new_entry;
|
| -
|
| - const base::DictionaryValue* old_entry = old_policies[guid];
|
| - if (!old_entry || !old_entry->Equals(new_entry))
|
| - modified_policies.insert(guid);
|
| - }
|
| -
|
| - STLDeleteValues(&old_policies);
|
| -
|
| - const NetworkProfile* profile =
|
| - network_profile_handler_->GetProfileForUserhash(userhash);
|
| - if (!profile) {
|
| - VLOG(1) << "The relevant Shill profile isn't initialized yet, postponing "
|
| - << "policy application.";
|
| - return;
|
| - }
|
| -
|
| - scoped_refptr<PolicyApplicator> applicator = new PolicyApplicator(
|
| - weak_ptr_factory_.GetWeakPtr(), *profile, policies, &modified_policies);
|
| - applicator->Run();
|
| -}
|
| -
|
| -void ManagedNetworkConfigurationHandlerImpl::OnProfileAdded(
|
| - const NetworkProfile& profile) {
|
| - VLOG(1) << "Adding profile " << profile.ToDebugString() << "'.";
|
| -
|
| - const GuidToPolicyMap* policies = GetPoliciesForProfile(profile);
|
| - if (!policies) {
|
| - VLOG(1) << "The relevant policy is not initialized, "
|
| - << "postponing policy application.";
|
| - return;
|
| - }
|
| -
|
| - std::set<std::string> policy_guids;
|
| - for (GuidToPolicyMap::const_iterator it = policies->begin();
|
| - it != policies->end(); ++it) {
|
| - policy_guids.insert(it->first);
|
| - }
|
| -
|
| - scoped_refptr<PolicyApplicator> applicator = new PolicyApplicator(
|
| - weak_ptr_factory_.GetWeakPtr(), profile, *policies, &policy_guids);
|
| - applicator->Run();
|
| -}
|
| -
|
| -const base::DictionaryValue*
|
| -ManagedNetworkConfigurationHandlerImpl::FindPolicyByGUID(
|
| - const std::string userhash,
|
| - const std::string& guid,
|
| - onc::ONCSource* onc_source) const {
|
| - *onc_source = onc::ONC_SOURCE_NONE;
|
| -
|
| - if (!userhash.empty()) {
|
| - const GuidToPolicyMap* user_policies = GetPoliciesForUser(userhash);
|
| - if (user_policies) {
|
| - GuidToPolicyMap::const_iterator found = user_policies->find(guid);
|
| - if (found != user_policies->end()) {
|
| - *onc_source = onc::ONC_SOURCE_USER_POLICY;
|
| - return found->second;
|
| - }
|
| - }
|
| - }
|
| -
|
| - const GuidToPolicyMap* device_policies = GetPoliciesForUser(std::string());
|
| - if (device_policies) {
|
| - GuidToPolicyMap::const_iterator found = device_policies->find(guid);
|
| - if (found != device_policies->end()) {
|
| - *onc_source = onc::ONC_SOURCE_DEVICE_POLICY;
|
| - return found->second;
|
| - }
|
| - }
|
| -
|
| - return NULL;
|
| -}
|
| -
|
| -const base::DictionaryValue*
|
| -ManagedNetworkConfigurationHandlerImpl::FindPolicyByGuidAndProfile(
|
| - const std::string& guid,
|
| - const std::string& profile_path) const {
|
| - const NetworkProfile* profile =
|
| - network_profile_handler_->GetProfileForPath(profile_path);
|
| - if (!profile) {
|
| - LOG(ERROR) << "Profile path unknown: " << profile_path;
|
| - return NULL;
|
| - }
|
| -
|
| - const GuidToPolicyMap* policies = GetPoliciesForProfile(*profile);
|
| - if (!policies)
|
| - return NULL;
|
| -
|
| - GuidToPolicyMap::const_iterator it = policies->find(guid);
|
| - if (it == policies->end())
|
| - return NULL;
|
| - return it->second;
|
| -}
|
| -
|
| -void ManagedNetworkConfigurationHandlerImpl::OnProfileRemoved(
|
| - const NetworkProfile& profile) {
|
| - // Nothing to do in this case.
|
| -}
|
| -
|
| -const ManagedNetworkConfigurationHandlerImpl::GuidToPolicyMap*
|
| -ManagedNetworkConfigurationHandlerImpl::GetPoliciesForUser(
|
| - const std::string& userhash) const {
|
| - UserToPoliciesMap::const_iterator it = policies_by_user_.find(userhash);
|
| - if (it == policies_by_user_.end())
|
| - return NULL;
|
| - return &it->second;
|
| -}
|
| -
|
| -const ManagedNetworkConfigurationHandlerImpl::GuidToPolicyMap*
|
| -ManagedNetworkConfigurationHandlerImpl::GetPoliciesForProfile(
|
| - const NetworkProfile& profile) const {
|
| - DCHECK(profile.type() != NetworkProfile::TYPE_SHARED ||
|
| - profile.userhash.empty());
|
| - return GetPoliciesForUser(profile.userhash);
|
| -}
|
| -
|
| -ManagedNetworkConfigurationHandlerImpl::ManagedNetworkConfigurationHandlerImpl()
|
| - : network_state_handler_(NULL),
|
| - network_profile_handler_(NULL),
|
| - network_configuration_handler_(NULL),
|
| - weak_ptr_factory_(this) {}
|
| -
|
| -ManagedNetworkConfigurationHandlerImpl::
|
| - ~ManagedNetworkConfigurationHandlerImpl() {
|
| - network_profile_handler_->RemoveObserver(this);
|
| - for (UserToPoliciesMap::iterator it = policies_by_user_.begin();
|
| - it != policies_by_user_.end(); ++it) {
|
| - STLDeleteValues(&it->second);
|
| - }
|
| -}
|
| -
|
| -void ManagedNetworkConfigurationHandlerImpl::Init(
|
| - NetworkStateHandler* network_state_handler,
|
| - NetworkProfileHandler* network_profile_handler,
|
| - NetworkConfigurationHandler* network_configuration_handler) {
|
| - network_state_handler_ = network_state_handler;
|
| - network_profile_handler_ = network_profile_handler;
|
| - network_configuration_handler_ = network_configuration_handler;
|
| - network_profile_handler_->AddObserver(this);
|
| -}
|
| -
|
| -void ManagedNetworkConfigurationHandlerImpl::OnPolicyApplied(
|
| - const std::string& service_path) {
|
| - if (service_path.empty())
|
| - return;
|
| - FOR_EACH_OBSERVER(
|
| - NetworkPolicyObserver, observers_, PolicyApplied(service_path));
|
| -}
|
| -
|
| -ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::PolicyApplicator(
|
| - base::WeakPtr<ManagedNetworkConfigurationHandlerImpl> handler,
|
| - const NetworkProfile& profile,
|
| - const GuidToPolicyMap& all_policies,
|
| - std::set<std::string>* modified_policies)
|
| +PolicyApplicator::PolicyApplicator(base::WeakPtr<ConfigurationHandler> handler,
|
| + const NetworkProfile& profile,
|
| + const GuidToPolicyMap& all_policies,
|
| + std::set<std::string>* modified_policies)
|
| : handler_(handler), profile_(profile) {
|
| remaining_policies_.swap(*modified_policies);
|
| for (GuidToPolicyMap::const_iterator it = all_policies.begin();
|
| @@ -810,16 +55,15 @@ ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::PolicyApplicator(
|
| }
|
| }
|
|
|
| -void ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::Run() {
|
| +void PolicyApplicator::Run() {
|
| DBusThreadManager::Get()->GetShillProfileClient()->GetProperties(
|
| dbus::ObjectPath(profile_.path),
|
| base::Bind(&PolicyApplicator::GetProfilePropertiesCallback, this),
|
| base::Bind(&LogErrorMessage, FROM_HERE));
|
| }
|
|
|
| -void ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::
|
| - GetProfilePropertiesCallback(
|
| - const base::DictionaryValue& profile_properties) {
|
| +void PolicyApplicator::GetProfilePropertiesCallback(
|
| + const base::DictionaryValue& profile_properties) {
|
| if (!handler_) {
|
| LOG(WARNING) << "Handler destructed during policy application to profile "
|
| << profile_.ToDebugString();
|
| @@ -829,7 +73,7 @@ void ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::
|
| VLOG(2) << "Received properties for profile " << profile_.ToDebugString();
|
| const base::ListValue* entries = NULL;
|
| if (!profile_properties.GetListWithoutPathExpansion(
|
| - flimflam::kEntriesProperty, &entries)) {
|
| + flimflam::kEntriesProperty, &entries)) {
|
| LOG(ERROR) << "Profile " << profile_.ToDebugString()
|
| << " doesn't contain the property "
|
| << flimflam::kEntriesProperty;
|
| @@ -837,20 +81,19 @@ void ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::
|
| }
|
|
|
| for (base::ListValue::const_iterator it = entries->begin();
|
| - it != entries->end();
|
| - ++it) {
|
| + it != entries->end(); ++it) {
|
| std::string entry;
|
| (*it)->GetAsString(&entry);
|
|
|
| - DBusThreadManager::Get()->GetShillProfileClient()
|
| - ->GetEntry(dbus::ObjectPath(profile_.path),
|
| - entry,
|
| - base::Bind(&PolicyApplicator::GetEntryCallback, this, entry),
|
| - base::Bind(&LogErrorMessage, FROM_HERE));
|
| + DBusThreadManager::Get()->GetShillProfileClient()->GetEntry(
|
| + dbus::ObjectPath(profile_.path),
|
| + entry,
|
| + base::Bind(&PolicyApplicator::GetEntryCallback, this, entry),
|
| + base::Bind(&LogErrorMessage, FROM_HERE));
|
| }
|
| }
|
|
|
| -void ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::GetEntryCallback(
|
| +void PolicyApplicator::GetEntryCallback(
|
| const std::string& entry,
|
| const base::DictionaryValue& entry_properties) {
|
| if (!handler_) {
|
| @@ -900,7 +143,7 @@ void ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::GetEntryCallback(
|
|
|
| if (!new_policy) {
|
| // If we didn't find a policy by GUID, still a new policy might match.
|
| - new_policy = FindMatchingPolicy(all_policies_, *onc_part);
|
| + new_policy = policy_util::FindMatchingPolicy(all_policies_, *onc_part);
|
| }
|
|
|
| if (new_policy) {
|
| @@ -954,8 +197,7 @@ void ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::GetEntryCallback(
|
| }
|
| }
|
|
|
| -void ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::DeleteEntry(
|
| - const std::string& entry) {
|
| +void PolicyApplicator::DeleteEntry(const std::string& entry) {
|
| DBusThreadManager::Get()->GetShillProfileClient()->DeleteEntry(
|
| dbus::ObjectPath(profile_.path),
|
| entry,
|
| @@ -963,27 +205,22 @@ void ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::DeleteEntry(
|
| base::Bind(&LogErrorMessage, FROM_HERE));
|
| }
|
|
|
| -void ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::
|
| - CreateAndWriteNewShillConfiguration(
|
| - const std::string& guid,
|
| - const base::DictionaryValue& policy,
|
| - const base::DictionaryValue* user_settings) {
|
| +void PolicyApplicator::CreateAndWriteNewShillConfiguration(
|
| + const std::string& guid,
|
| + const base::DictionaryValue& policy,
|
| + const base::DictionaryValue* user_settings) {
|
| scoped_ptr<base::DictionaryValue> shill_dictionary =
|
| - CreateShillConfiguration(profile_, guid, &policy, user_settings);
|
| - handler_->network_configuration_handler()->CreateConfiguration(
|
| - *shill_dictionary,
|
| - base::Bind(&ManagedNetworkConfigurationHandlerImpl::OnPolicyApplied,
|
| - handler_),
|
| - base::Bind(&LogErrorWithDict, FROM_HERE));
|
| + policy_util::CreateShillConfiguration(
|
| + profile_, guid, &policy, user_settings);
|
| + handler_->CreateConfigurationFromPolicy(*shill_dictionary);
|
| }
|
|
|
| -ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::~PolicyApplicator() {
|
| +PolicyApplicator::~PolicyApplicator() {
|
| ApplyRemainingPolicies();
|
| STLDeleteValues(&all_policies_);
|
| }
|
|
|
| -void ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::
|
| - ApplyRemainingPolicies() {
|
| +void PolicyApplicator::ApplyRemainingPolicies() {
|
| if (!handler_) {
|
| LOG(WARNING) << "Handler destructed during policy application to profile "
|
| << profile_.ToDebugString();
|
| @@ -998,10 +235,8 @@ void ManagedNetworkConfigurationHandlerImpl::PolicyApplicator::
|
| // All profile entries were compared to policies. |remaining_policies_|
|
| // contains all modified policies that didn't match any entry. For these
|
| // remaining policies, new configurations have to be created.
|
| -
|
| for (std::set<std::string>::iterator it = remaining_policies_.begin();
|
| - it != remaining_policies_.end();
|
| - ++it) {
|
| + it != remaining_policies_.end(); ++it) {
|
| const base::DictionaryValue* policy = GetByGUID(all_policies_, *it);
|
| DCHECK(policy);
|
|
|
|
|