// Copyright (c) 2012 The Chromium 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 "chrome_frame/policy_settings.h" #include <algorithm> #include "base/logging.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/win/registry.h" #include "chrome_frame/utils.h" #include "policy/policy_constants.h" namespace { // This array specifies the order in which registry keys are tested. Do not // change this unless the decision is made product-wide (i.e., in Chrome's // configuration policy provider). const HKEY kRootKeys[] = { HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER }; } // namespace PolicySettings::RendererForUrl PolicySettings::GetRendererForUrl( const wchar_t* url) { RendererForUrl renderer = default_renderer_; std::vector<std::wstring>::const_iterator it; for (it = renderer_exclusion_list_.begin(); it != renderer_exclusion_list_.end(); ++it) { if (MatchPattern(url, (*it))) { renderer = (renderer == RENDER_IN_HOST) ? RENDER_IN_CHROME_FRAME : RENDER_IN_HOST; break; } } return renderer; } PolicySettings::RendererForUrl PolicySettings::GetRendererForContentType( const wchar_t* content_type) { DCHECK(content_type); RendererForUrl renderer = RENDERER_NOT_SPECIFIED; std::vector<std::wstring>::const_iterator it; for (it = content_type_list_.begin(); it != content_type_list_.end(); ++it) { if (lstrcmpiW(content_type, (*it).c_str()) == 0) { renderer = RENDER_IN_CHROME_FRAME; break; } } return renderer; } const CommandLine& PolicySettings::AdditionalLaunchParameters() const { return additional_launch_parameters_; } // static void PolicySettings::ReadUrlSettings( RendererForUrl* default_renderer, std::vector<std::wstring>* renderer_exclusion_list) { DCHECK(default_renderer); DCHECK(renderer_exclusion_list); *default_renderer = RENDERER_NOT_SPECIFIED; renderer_exclusion_list->clear(); base::win::RegKey config_key; DWORD value = RENDERER_NOT_SPECIFIED; std::wstring settings_value( ASCIIToWide(policy::key::kChromeFrameRendererSettings)); for (int i = 0; i < arraysize(kRootKeys); ++i) { if ((config_key.Open(kRootKeys[i], policy::kRegistryChromePolicyKey, KEY_READ) == ERROR_SUCCESS) && (config_key.ReadValueDW(settings_value.c_str(), &value) == ERROR_SUCCESS)) { break; } } DCHECK(value == RENDERER_NOT_SPECIFIED || value == RENDER_IN_HOST || value == RENDER_IN_CHROME_FRAME) << "invalid default renderer setting: " << value; if (value != RENDER_IN_HOST && value != RENDER_IN_CHROME_FRAME) { DVLOG(1) << "default renderer not specified via policy"; } else { *default_renderer = static_cast<RendererForUrl>(value); const char* exclusion_list_name = (*default_renderer == RENDER_IN_HOST) ? policy::key::kRenderInChromeFrameList : policy::key::kRenderInHostList; EnumerateKeyValues(config_key.Handle(), ASCIIToWide(exclusion_list_name).c_str(), renderer_exclusion_list); DVLOG(1) << "Default renderer as specified via policy: " << *default_renderer << " exclusion list size: " << renderer_exclusion_list->size(); } } // static void PolicySettings::ReadMetadataCheckSettings( SkipMetadataCheck* skip_metadata_check) { DCHECK(skip_metadata_check); *skip_metadata_check = SKIP_METADATA_CHECK_NOT_SPECIFIED; base::win::RegKey config_key; DWORD value = SKIP_METADATA_CHECK_NOT_SPECIFIED; string16 settings_value( ASCIIToWide(policy::key::kSkipMetadataCheck)); for (int i = 0; i < arraysize(kRootKeys); ++i) { if ((config_key.Open(kRootKeys[i], policy::kRegistryChromePolicyKey, KEY_READ) == ERROR_SUCCESS) && (config_key.ReadValueDW(settings_value.c_str(), &value) == ERROR_SUCCESS)) { break; } } DCHECK(value == SKIP_METADATA_CHECK_NOT_SPECIFIED || value == SKIP_METADATA_CHECK_NO || value == SKIP_METADATA_CHECK_YES) << "invalid skip metadata check setting: " << value; if (value != SKIP_METADATA_CHECK_NO && value != SKIP_METADATA_CHECK_YES) { DVLOG(1) << "metadata check not specified via policy"; } else { *skip_metadata_check = static_cast<SkipMetadataCheck>(value); DVLOG(1) << "SkipMetadata check as specified via policy: " << *skip_metadata_check; } } // static void PolicySettings::ReadContentTypeSetting( std::vector<std::wstring>* content_type_list) { DCHECK(content_type_list); std::wstring sub_key(policy::kRegistryChromePolicyKey); sub_key += L"\\"; sub_key += ASCIIToWide(policy::key::kChromeFrameContentTypes); content_type_list->clear(); for (int i = 0; i < arraysize(kRootKeys) && content_type_list->empty(); ++i) { EnumerateKeyValues(kRootKeys[i], sub_key.c_str(), content_type_list); } } // static void PolicySettings::ReadStringSetting(const char* value_name, std::wstring* value) { DCHECK(value); value->clear(); base::win::RegKey config_key; std::wstring value_name_str(ASCIIToWide(value_name)); for (int i = 0; i < arraysize(kRootKeys); ++i) { if ((config_key.Open(kRootKeys[i], policy::kRegistryChromePolicyKey, KEY_READ) == ERROR_SUCCESS) && (config_key.ReadValue(value_name_str.c_str(), value) == ERROR_SUCCESS)) { break; } } } // static void PolicySettings::ReadBoolSetting(const char* value_name, bool* value) { DCHECK(value); base::win::RegKey config_key; string16 value_name_str(ASCIIToWide(value_name)); DWORD dword_value = 0; for (int i = 0; i < arraysize(kRootKeys); ++i) { if ((config_key.Open(kRootKeys[i], policy::kRegistryChromePolicyKey, KEY_QUERY_VALUE) == ERROR_SUCCESS) && (config_key.ReadValueDW(value_name_str.c_str(), &dword_value) == ERROR_SUCCESS)) { *value = (dword_value != 0); break; } } } void PolicySettings::RefreshFromRegistry() { RendererForUrl default_renderer; SkipMetadataCheck skip_metadata_check; std::vector<std::wstring> renderer_exclusion_list; std::vector<std::wstring> content_type_list; std::wstring application_locale; CommandLine additional_launch_parameters(CommandLine::NO_PROGRAM); std::wstring additional_parameters_str; bool suppress_turndown_prompt = false; // Read the latest settings from the registry ReadUrlSettings(&default_renderer, &renderer_exclusion_list); ReadMetadataCheckSettings(&skip_metadata_check); ReadContentTypeSetting(&content_type_list); ReadStringSetting(policy::key::kApplicationLocaleValue, &application_locale); ReadStringSetting(policy::key::kAdditionalLaunchParameters, &additional_parameters_str); if (!additional_parameters_str.empty()) { additional_parameters_str.insert(0, L"fake.exe "); additional_launch_parameters.ParseFromString(additional_parameters_str); } ReadBoolSetting(policy::key::kSuppressChromeFrameTurndownPrompt, &suppress_turndown_prompt); // Nofail swap in the new values. (Note: this is all that need be protected // under a mutex if/when this becomes thread safe.) using std::swap; swap(default_renderer_, default_renderer); swap(skip_metadata_check_, skip_metadata_check); swap(renderer_exclusion_list_, renderer_exclusion_list); swap(content_type_list_, content_type_list); swap(application_locale_, application_locale); swap(additional_launch_parameters_, additional_launch_parameters); swap(suppress_turndown_prompt_, suppress_turndown_prompt); } // static PolicySettings* PolicySettings::GetInstance() { return Singleton<PolicySettings>::get(); }