1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome_frame/policy_settings.h" 6 7 #include <algorithm> 8 9 #include "base/logging.h" 10 #include "base/strings/string_util.h" 11 #include "base/strings/utf_string_conversions.h" 12 #include "base/win/registry.h" 13 #include "chrome_frame/utils.h" 14 #include "policy/policy_constants.h" 15 16 namespace { 17 18 // This array specifies the order in which registry keys are tested. Do not 19 // change this unless the decision is made product-wide (i.e., in Chrome's 20 // configuration policy provider). 21 const HKEY kRootKeys[] = { 22 HKEY_LOCAL_MACHINE, 23 HKEY_CURRENT_USER 24 }; 25 26 } // namespace 27 28 PolicySettings::RendererForUrl PolicySettings::GetRendererForUrl( 29 const wchar_t* url) { 30 RendererForUrl renderer = default_renderer_; 31 std::vector<std::wstring>::const_iterator it; 32 for (it = renderer_exclusion_list_.begin(); 33 it != renderer_exclusion_list_.end(); ++it) { 34 if (MatchPattern(url, (*it))) { 35 renderer = (renderer == RENDER_IN_HOST) ? 36 RENDER_IN_CHROME_FRAME : RENDER_IN_HOST; 37 break; 38 } 39 } 40 return renderer; 41 } 42 43 PolicySettings::RendererForUrl PolicySettings::GetRendererForContentType( 44 const wchar_t* content_type) { 45 DCHECK(content_type); 46 RendererForUrl renderer = RENDERER_NOT_SPECIFIED; 47 std::vector<std::wstring>::const_iterator it; 48 for (it = content_type_list_.begin(); 49 it != content_type_list_.end(); ++it) { 50 if (lstrcmpiW(content_type, (*it).c_str()) == 0) { 51 renderer = RENDER_IN_CHROME_FRAME; 52 break; 53 } 54 } 55 return renderer; 56 } 57 58 const CommandLine& PolicySettings::AdditionalLaunchParameters() const { 59 return additional_launch_parameters_; 60 } 61 62 // static 63 void PolicySettings::ReadUrlSettings( 64 RendererForUrl* default_renderer, 65 std::vector<std::wstring>* renderer_exclusion_list) { 66 DCHECK(default_renderer); 67 DCHECK(renderer_exclusion_list); 68 69 *default_renderer = RENDERER_NOT_SPECIFIED; 70 renderer_exclusion_list->clear(); 71 72 base::win::RegKey config_key; 73 DWORD value = RENDERER_NOT_SPECIFIED; 74 std::wstring settings_value( 75 ASCIIToWide(policy::key::kChromeFrameRendererSettings)); 76 for (int i = 0; i < arraysize(kRootKeys); ++i) { 77 if ((config_key.Open(kRootKeys[i], policy::kRegistryChromePolicyKey, 78 KEY_READ) == ERROR_SUCCESS) && 79 (config_key.ReadValueDW(settings_value.c_str(), 80 &value) == ERROR_SUCCESS)) { 81 break; 82 } 83 } 84 85 DCHECK(value == RENDERER_NOT_SPECIFIED || 86 value == RENDER_IN_HOST || 87 value == RENDER_IN_CHROME_FRAME) 88 << "invalid default renderer setting: " << value; 89 90 if (value != RENDER_IN_HOST && value != RENDER_IN_CHROME_FRAME) { 91 DVLOG(1) << "default renderer not specified via policy"; 92 } else { 93 *default_renderer = static_cast<RendererForUrl>(value); 94 const char* exclusion_list_name = (*default_renderer == RENDER_IN_HOST) ? 95 policy::key::kRenderInChromeFrameList : 96 policy::key::kRenderInHostList; 97 98 EnumerateKeyValues(config_key.Handle(), 99 ASCIIToWide(exclusion_list_name).c_str(), renderer_exclusion_list); 100 101 DVLOG(1) << "Default renderer as specified via policy: " 102 << *default_renderer 103 << " exclusion list size: " << renderer_exclusion_list->size(); 104 } 105 } 106 107 // static 108 void PolicySettings::ReadMetadataCheckSettings( 109 SkipMetadataCheck* skip_metadata_check) { 110 DCHECK(skip_metadata_check); 111 112 *skip_metadata_check = SKIP_METADATA_CHECK_NOT_SPECIFIED; 113 114 base::win::RegKey config_key; 115 DWORD value = SKIP_METADATA_CHECK_NOT_SPECIFIED; 116 string16 settings_value( 117 ASCIIToWide(policy::key::kSkipMetadataCheck)); 118 for (int i = 0; i < arraysize(kRootKeys); ++i) { 119 if ((config_key.Open(kRootKeys[i], policy::kRegistryChromePolicyKey, 120 KEY_READ) == ERROR_SUCCESS) && 121 (config_key.ReadValueDW(settings_value.c_str(), 122 &value) == ERROR_SUCCESS)) { 123 break; 124 } 125 } 126 127 DCHECK(value == SKIP_METADATA_CHECK_NOT_SPECIFIED || 128 value == SKIP_METADATA_CHECK_NO || 129 value == SKIP_METADATA_CHECK_YES) 130 << "invalid skip metadata check setting: " << value; 131 132 if (value != SKIP_METADATA_CHECK_NO && value != SKIP_METADATA_CHECK_YES) { 133 DVLOG(1) << "metadata check not specified via policy"; 134 } else { 135 *skip_metadata_check = static_cast<SkipMetadataCheck>(value); 136 DVLOG(1) << "SkipMetadata check as specified via policy: " 137 << *skip_metadata_check; 138 } 139 } 140 141 // static 142 void PolicySettings::ReadContentTypeSetting( 143 std::vector<std::wstring>* content_type_list) { 144 DCHECK(content_type_list); 145 146 std::wstring sub_key(policy::kRegistryChromePolicyKey); 147 sub_key += L"\\"; 148 sub_key += ASCIIToWide(policy::key::kChromeFrameContentTypes); 149 150 content_type_list->clear(); 151 for (int i = 0; i < arraysize(kRootKeys) && content_type_list->empty(); 152 ++i) { 153 EnumerateKeyValues(kRootKeys[i], sub_key.c_str(), content_type_list); 154 } 155 } 156 157 // static 158 void PolicySettings::ReadStringSetting(const char* value_name, 159 std::wstring* value) { 160 DCHECK(value); 161 value->clear(); 162 base::win::RegKey config_key; 163 std::wstring value_name_str(ASCIIToWide(value_name)); 164 for (int i = 0; i < arraysize(kRootKeys); ++i) { 165 if ((config_key.Open(kRootKeys[i], policy::kRegistryChromePolicyKey, 166 KEY_READ) == ERROR_SUCCESS) && 167 (config_key.ReadValue(value_name_str.c_str(), 168 value) == ERROR_SUCCESS)) { 169 break; 170 } 171 } 172 } 173 174 // static 175 void PolicySettings::ReadBoolSetting(const char* value_name, bool* value) { 176 DCHECK(value); 177 base::win::RegKey config_key; 178 string16 value_name_str(ASCIIToWide(value_name)); 179 DWORD dword_value = 0; 180 for (int i = 0; i < arraysize(kRootKeys); ++i) { 181 if ((config_key.Open(kRootKeys[i], policy::kRegistryChromePolicyKey, 182 KEY_QUERY_VALUE) == ERROR_SUCCESS) && 183 (config_key.ReadValueDW(value_name_str.c_str(), 184 &dword_value) == ERROR_SUCCESS)) { 185 *value = (dword_value != 0); 186 break; 187 } 188 } 189 } 190 191 void PolicySettings::RefreshFromRegistry() { 192 RendererForUrl default_renderer; 193 SkipMetadataCheck skip_metadata_check; 194 std::vector<std::wstring> renderer_exclusion_list; 195 std::vector<std::wstring> content_type_list; 196 std::wstring application_locale; 197 CommandLine additional_launch_parameters(CommandLine::NO_PROGRAM); 198 std::wstring additional_parameters_str; 199 bool suppress_turndown_prompt = false; 200 201 // Read the latest settings from the registry 202 ReadUrlSettings(&default_renderer, &renderer_exclusion_list); 203 ReadMetadataCheckSettings(&skip_metadata_check); 204 ReadContentTypeSetting(&content_type_list); 205 ReadStringSetting(policy::key::kApplicationLocaleValue, &application_locale); 206 ReadStringSetting(policy::key::kAdditionalLaunchParameters, 207 &additional_parameters_str); 208 if (!additional_parameters_str.empty()) { 209 additional_parameters_str.insert(0, L"fake.exe "); 210 additional_launch_parameters.ParseFromString(additional_parameters_str); 211 } 212 ReadBoolSetting(policy::key::kSuppressChromeFrameTurndownPrompt, 213 &suppress_turndown_prompt); 214 215 // Nofail swap in the new values. (Note: this is all that need be protected 216 // under a mutex if/when this becomes thread safe.) 217 using std::swap; 218 219 swap(default_renderer_, default_renderer); 220 swap(skip_metadata_check_, skip_metadata_check); 221 swap(renderer_exclusion_list_, renderer_exclusion_list); 222 swap(content_type_list_, content_type_list); 223 swap(application_locale_, application_locale); 224 swap(additional_launch_parameters_, additional_launch_parameters); 225 swap(suppress_turndown_prompt_, suppress_turndown_prompt); 226 } 227 228 // static 229 PolicySettings* PolicySettings::GetInstance() { 230 return Singleton<PolicySettings>::get(); 231 } 232