blob: 17828230c309ca9f292b4bdc5b24e05d88128b26 [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 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.
initial.commit09911bf2008-07-26 23:55:294
5#include "chrome/browser/sandbox_policy.h"
6
7#include "base/file_util.h"
8#include "base/logging.h"
9#include "base/path_service.h"
10#include "base/registry.h"
11#include "base/string_util.h"
12#include "base/win_util.h"
13#include "chrome/common/chrome_constants.h"
14#include "chrome/common/chrome_paths.h"
15#include "chrome/common/ipc_logging.h"
16#include "chrome/common/win_util.h"
17#include "webkit/glue/plugins/plugin_list.h"
18
19PluginPolicyCategory GetPolicyCategoryForPlugin(
20 const std::wstring& dll,
21 const std::wstring& clsid,
22 const std::wstring& list) {
23 std::wstring filename = file_util::GetFilenameFromPath(dll);
24 std::wstring plugin_dll = StringToLowerASCII(filename);
25 std::wstring trusted_plugins = StringToLowerASCII(list);
26 std::wstring activex_clsid = StringToLowerASCII(clsid);
27
28 size_t pos = 0;
29 size_t end_item = 0;
30 while(end_item != std::wstring::npos) {
31 end_item = list.find(L",", pos);
32
33 size_t size_item = (end_item == std::wstring::npos) ? end_item :
34 end_item - pos;
35 std::wstring item = list.substr(pos, size_item);
36 if (!item.empty()) {
37 if (item == activex_clsid || item == plugin_dll)
38 return PLUGIN_GROUP_TRUSTED;
39 }
40
41 pos = end_item + 1;
42 }
43
44 return PLUGIN_GROUP_UNTRUSTED;
45}
46
47// Adds the policy rules for the path and path\* with the semantic |access|.
48// We need to add the wildcard rules to also apply the rule to the subfiles
49// and subfolders.
50bool AddDirectoryAndChildren(int path, const wchar_t* sub_dir,
51 sandbox::TargetPolicy::Semantics access,
52 sandbox::TargetPolicy* policy) {
53 std::wstring directory;
54 if (!PathService::Get(path, &directory))
55 return false;
56
57 if (sub_dir)
58 file_util::AppendToPath(&directory, sub_dir);
59
60 sandbox::ResultCode result;
61 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, access,
62 directory.c_str());
63 if (result != sandbox::SBOX_ALL_OK)
64 return false;
65
66 file_util::AppendToPath(&directory, L"*");
67 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES, access,
68 directory.c_str());
69 if (result != sandbox::SBOX_ALL_OK)
70 return false;
71
72 return true;
73}
74
75// Adds the policy rules for the path and path\* with the semantic |access|.
76// We need to add the wildcard rules to also apply the rule to the subkeys.
77bool AddKeyAndSubkeys(std::wstring key,
78 sandbox::TargetPolicy::Semantics access,
79 sandbox::TargetPolicy* policy) {
80 sandbox::ResultCode result;
81 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_REGISTRY, access,
82 key.c_str());
83 if (result != sandbox::SBOX_ALL_OK)
84 return false;
85
86 key += L"\\*";
87 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_REGISTRY, access,
88 key.c_str());
89 if (result != sandbox::SBOX_ALL_OK)
90 return false;
91
92 return true;
93}
94
95bool AddGenericPolicy(sandbox::TargetPolicy* policy) {
96 sandbox::ResultCode result;
97
98 // Add the policy for the pipes
99 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
100 sandbox::TargetPolicy::FILES_ALLOW_ANY,
101 L"\\??\\pipe\\chrome.*");
102 if (result != sandbox::SBOX_ALL_OK)
103 return false;
104
105#ifdef IPC_MESSAGE_LOG_ENABLED
106 // Add the policy for the IPC logging events.
107 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_SYNC,
108 sandbox::TargetPolicy::EVENTS_ALLOW_ANY,
109 IPC::Logging::GetEventName(true).c_str());
110 if (result != sandbox::SBOX_ALL_OK)
111 return false;
112
113 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_SYNC,
114 sandbox::TargetPolicy::EVENTS_ALLOW_ANY,
115 IPC::Logging::GetEventName(false).c_str());
116 if (result != sandbox::SBOX_ALL_OK)
117 return false;
118#endif
119
120 // Add the policy for debug message only in debug
121#ifndef NDEBUG
122 std::wstring debug_message;
123 if (!PathService::Get(chrome::DIR_APP, &debug_message))
124 return false;
125 if (!win_util::ConvertToLongPath(debug_message, &debug_message))
126 return false;
127 file_util::AppendToPath(&debug_message, L"debug_message.exe");
128 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_PROCESS,
129 sandbox::TargetPolicy::PROCESS_MIN_EXEC,
130 debug_message.c_str());
131 if (result != sandbox::SBOX_ALL_OK)
132 return false;
133#endif // NDEBUG
134
135 return true;
136}
137
138bool ApplyPolicyForTrustedPlugin(sandbox::TargetPolicy* policy) {
139 policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0);
140 policy->SetTokenLevel(sandbox::USER_UNPROTECTED, sandbox::USER_UNPROTECTED);
141 return true;
142}
143
144bool ApplyPolicyForUntrustedPlugin(sandbox::TargetPolicy* policy) {
145 policy->SetJobLevel(sandbox::JOB_UNPROTECTED, 0);
146
147 sandbox::TokenLevel initial_token = sandbox::USER_UNPROTECTED;
148 if (win_util::GetWinVersion() > win_util::WINVERSION_XP) {
149 // On 2003/Vista the initial token has to be restricted if the main token
150 // is restricted.
151 initial_token = sandbox::USER_RESTRICTED_SAME_ACCESS;
152 }
153 policy->SetTokenLevel(initial_token, sandbox::USER_LIMITED);
154 policy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
155
156 if (!AddDirectoryAndChildren(base::DIR_TEMP, NULL,
157 sandbox::TargetPolicy::FILES_ALLOW_ANY, policy))
158 return false;
159
160 if (!AddDirectoryAndChildren(base::DIR_IE_INTERNET_CACHE, NULL,
161 sandbox::TargetPolicy::FILES_ALLOW_ANY, policy))
162 return false;
163
164
165 if (!AddDirectoryAndChildren(base::DIR_APP_DATA, NULL,
166 sandbox::TargetPolicy::FILES_ALLOW_READONLY,
167 policy))
168 return false;
169
170 if (!AddDirectoryAndChildren(base::DIR_APP_DATA, L"Macromedia",
171 sandbox::TargetPolicy::FILES_ALLOW_ANY,
172 policy))
173 return false;
174
175 if (!AddDirectoryAndChildren(base::DIR_LOCAL_APP_DATA, NULL,
176 sandbox::TargetPolicy::FILES_ALLOW_READONLY,
177 policy))
178 return false;
179
180 if (!AddKeyAndSubkeys(L"HKEY_CURRENT_USER\\SOFTWARE\\MACROMEDIA",
181 sandbox::TargetPolicy::REG_ALLOW_ANY,
182 policy))
183 return false;
184
185 if (win_util::GetWinVersion() == win_util::WINVERSION_VISTA) {
186 if (!AddKeyAndSubkeys(L"HKEY_CURRENT_USER\\SOFTWARE\\AppDataLow",
187 sandbox::TargetPolicy::REG_ALLOW_ANY,
188 policy))
189 return false;
190
191 if (!AddDirectoryAndChildren(base::DIR_LOCAL_APP_DATA_LOW, NULL,
192 sandbox::TargetPolicy::FILES_ALLOW_ANY,
193 policy))
194 return false;
195 }
196
197 return true;
198}
199
200bool AddPolicyForPlugin(const std::wstring &plugin_dll,
201 const std::string &activex_clsid,
202 const std::wstring &trusted_plugins,
203 sandbox::TargetPolicy* policy) {
204 // Add the policy for the pipes.
205 sandbox::ResultCode result = sandbox::SBOX_ALL_OK;
206 result = policy->AddRule(sandbox::TargetPolicy::SUBSYS_NAMED_PIPES,
207 sandbox::TargetPolicy::NAMEDPIPES_ALLOW_ANY,
208 L"\\\\.\\pipe\\chrome.*");
209 if (result != sandbox::SBOX_ALL_OK)
210 return false;
211
212 std::wstring clsid = UTF8ToWide(activex_clsid);
213
214 PluginPolicyCategory policy_category =
215 GetPolicyCategoryForPlugin(plugin_dll, clsid, trusted_plugins);
216
217 switch (policy_category) {
218 case PLUGIN_GROUP_TRUSTED:
219 return ApplyPolicyForTrustedPlugin(policy);
220 case PLUGIN_GROUP_UNTRUSTED:
221 return ApplyPolicyForUntrustedPlugin(policy);
222 default:
223 NOTREACHED();
224 break;
225 }
226
227 return false;
license.botbf09a502008-08-24 00:55:55228}