OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <htiframe.h> | 5 #include <htiframe.h> |
6 #include <mshtml.h> | 6 #include <mshtml.h> |
7 #include <shlobj.h> | 7 #include <shlobj.h> |
8 #include <wininet.h> | 8 #include <wininet.h> |
9 | 9 |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 // lower-case-transformed values. | 36 // lower-case-transformed values. |
37 const wchar_t kMetaTag[] = L"meta"; | 37 const wchar_t kMetaTag[] = L"meta"; |
38 const wchar_t kHttpEquivAttribName[] = L"http-equiv"; | 38 const wchar_t kHttpEquivAttribName[] = L"http-equiv"; |
39 const wchar_t kContentAttribName[] = L"content"; | 39 const wchar_t kContentAttribName[] = L"content"; |
40 const wchar_t kXUACompatValue[] = L"x-ua-compatible"; | 40 const wchar_t kXUACompatValue[] = L"x-ua-compatible"; |
41 const wchar_t kBodyTag[] = L"body"; | 41 const wchar_t kBodyTag[] = L"body"; |
42 const wchar_t kChromeContentPrefix[] = L"chrome="; | 42 const wchar_t kChromeContentPrefix[] = L"chrome="; |
43 const wchar_t kChromeProtocolPrefix[] = L"gcf:"; | 43 const wchar_t kChromeProtocolPrefix[] = L"gcf:"; |
44 const wchar_t kChromeMimeType[] = L"application/chromepage"; | 44 const wchar_t kChromeMimeType[] = L"application/chromepage"; |
45 const wchar_t kPatchProtocols[] = L"PatchProtocols"; | 45 const wchar_t kPatchProtocols[] = L"PatchProtocols"; |
| 46 const wchar_t kChromeFrameAttachTabPattern[] = L"*?attach_external_tab&*"; |
46 | 47 |
47 static const wchar_t kChromeFrameConfigKey[] = | 48 static const wchar_t kChromeFrameConfigKey[] = |
48 L"Software\\Google\\ChromeFrame"; | 49 L"Software\\Google\\ChromeFrame"; |
49 static const wchar_t kChromeFrameOptinUrlsKey[] = L"OptinUrls"; | 50 static const wchar_t kChromeFrameOptinUrlsKey[] = L"OptinUrls"; |
50 static const wchar_t kEnableGCFProtocol[] = L"EnableGCFProtocol"; | 51 static const wchar_t kEnableGCFProtocol[] = L"EnableGCFProtocol"; |
51 static const wchar_t kEnableBuggyBhoIntercept[] = L"EnableBuggyBhoIntercept"; | 52 static const wchar_t kEnableBuggyBhoIntercept[] = L"EnableBuggyBhoIntercept"; |
52 | 53 |
53 static const wchar_t kChromeFrameNPAPIKey[] = | 54 static const wchar_t kChromeFrameNPAPIKey[] = |
54 L"Software\\MozillaPlugins\\@google.com/ChromeFrame,version=1.0"; | 55 L"Software\\MozillaPlugins\\@google.com/ChromeFrame,version=1.0"; |
55 static const wchar_t kChromeFramePersistNPAPIReg[] = L"PersistNPAPIReg"; | 56 static const wchar_t kChromeFramePersistNPAPIReg[] = L"PersistNPAPIReg"; |
56 | 57 |
57 // Used to isolate chrome frame builds from google chrome release channels. | 58 // Used to isolate chrome frame builds from google chrome release channels. |
58 const wchar_t kChromeFrameOmahaSuffix[] = L"-cf"; | 59 const wchar_t kChromeFrameOmahaSuffix[] = L"-cf"; |
59 const wchar_t kDevChannelName[] = L"-dev"; | 60 const wchar_t kDevChannelName[] = L"-dev"; |
60 | 61 |
61 const wchar_t kChromeAttachExternalTabPrefix[] = L"attach_external_tab"; | 62 const wchar_t kChromeAttachExternalTabPrefix[] = L"?attach_external_tab"; |
62 | 63 |
63 // Indicates that we are running in a test environment, where execptions, etc | 64 // Indicates that we are running in a test environment, where execptions, etc |
64 // are handled by the chrome test crash server. | 65 // are handled by the chrome test crash server. |
65 const wchar_t kChromeFrameHeadlessMode[] = L"ChromeFrameHeadlessMode"; | 66 const wchar_t kChromeFrameHeadlessMode[] = L"ChromeFrameHeadlessMode"; |
66 | 67 |
67 // Indicates that we are running in an environment that wishes to avoid | 68 // Indicates that we are running in an environment that wishes to avoid |
68 // DLL pinning, such as the perf tests. | 69 // DLL pinning, such as the perf tests. |
69 const wchar_t kChromeFrameUnpinnedMode[] = L"kChromeFrameUnpinnedMode"; | 70 const wchar_t kChromeFrameUnpinnedMode[] = L"kChromeFrameUnpinnedMode"; |
70 | 71 |
71 // {1AF32B6C-A3BA-48B9-B24E-8AA9C41F6ECD} | 72 // {1AF32B6C-A3BA-48B9-B24E-8AA9C41F6ECD} |
(...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
851 return true; | 852 return true; |
852 else | 853 else |
853 return false; | 854 return false; |
854 } | 855 } |
855 | 856 |
856 if (is_privileged && | 857 if (is_privileged && |
857 (crack_url.SchemeIs(chrome::kDataScheme) || | 858 (crack_url.SchemeIs(chrome::kDataScheme) || |
858 crack_url.SchemeIs(chrome::kExtensionScheme))) | 859 crack_url.SchemeIs(chrome::kExtensionScheme))) |
859 return true; | 860 return true; |
860 | 861 |
861 if (StartsWith(url, kChromeAttachExternalTabPrefix, false)) | |
862 return true; | |
863 | |
864 return false; | 862 return false; |
865 } | 863 } |
866 | 864 |
867 std::string GetRawHttpHeaders(IWinInetHttpInfo* info) { | 865 std::string GetRawHttpHeaders(IWinInetHttpInfo* info) { |
868 DCHECK(info); | 866 DCHECK(info); |
869 | 867 |
870 std::string buffer; | 868 std::string buffer; |
871 | 869 |
872 DWORD size = 0; | 870 DWORD size = 0; |
873 DWORD flags = 0; | 871 DWORD flags = 0; |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 } else { | 1229 } else { |
1232 data->clear(); | 1230 data->clear(); |
1233 // Return S_FALSE if the underlying stream returned S_OK and zero bytes. | 1231 // Return S_FALSE if the underlying stream returned S_OK and zero bytes. |
1234 if (hr == S_OK) | 1232 if (hr == S_OK) |
1235 hr = S_FALSE; | 1233 hr = S_FALSE; |
1236 } | 1234 } |
1237 | 1235 |
1238 return hr; | 1236 return hr; |
1239 } | 1237 } |
1240 | 1238 |
1241 bool ParseAttachExternalTabUrl(const std::wstring& url, uint64* cookie, | 1239 ChromeFrameUrl::ChromeFrameUrl() |
1242 gfx::Rect* dimensions, int* disposition) { | 1240 : is_chrome_protocol_(false), |
1243 if (!StartsWith(url, kChromeAttachExternalTabPrefix, true)) { | 1241 attach_to_external_tab_(false), |
1244 DLOG(WARNING) << "Invalid url passed in:" | 1242 cookie_(0), |
1245 << url.c_str(); | 1243 disposition_(0) { |
| 1244 } |
| 1245 |
| 1246 bool ChromeFrameUrl::Parse(const std::wstring& url) { |
| 1247 bool ret = false; |
| 1248 if (url.empty()) |
| 1249 return ret; |
| 1250 |
| 1251 url_ = url; |
| 1252 |
| 1253 attach_to_external_tab_ = MatchPatternWide(url.c_str(), |
| 1254 kChromeFrameAttachTabPattern); |
| 1255 is_chrome_protocol_ = StartsWith(url, kChromeProtocolPrefix, |
| 1256 false); |
| 1257 DCHECK(!(attach_to_external_tab_ && is_chrome_protocol_)); |
| 1258 if (is_chrome_protocol_) { |
| 1259 url_.erase(0, lstrlen(kChromeProtocolPrefix)); |
| 1260 } |
| 1261 |
| 1262 if (attach_to_external_tab_) { |
| 1263 ret = ParseAttachExternalTabUrl(); |
| 1264 } else { |
| 1265 ret = true; |
| 1266 } |
| 1267 return ret; |
| 1268 } |
| 1269 |
| 1270 bool ChromeFrameUrl::ParseAttachExternalTabUrl() { |
| 1271 size_t attach_external_tab_start_pos = |
| 1272 url_.find(kChromeAttachExternalTabPrefix); |
| 1273 if (attach_external_tab_start_pos == std::wstring::npos) { |
| 1274 NOTREACHED() << "Invalid url:" << url_; |
1246 return false; | 1275 return false; |
1247 } | 1276 } |
1248 | 1277 |
1249 if (!cookie || !dimensions || !disposition) | 1278 std::wstring url = |
1250 return false; | 1279 url_.substr(attach_external_tab_start_pos, |
| 1280 url_.length() - attach_external_tab_start_pos); |
1251 | 1281 |
1252 WStringTokenizer tokenizer(url, L"&"); | 1282 WStringTokenizer tokenizer(url, L"&"); |
1253 // Skip over kChromeAttachExternalTabPrefix | 1283 // Skip over kChromeAttachExternalTabPrefix |
1254 tokenizer.GetNext(); | 1284 tokenizer.GetNext(); |
1255 | |
1256 // Read the following items in order. | 1285 // Read the following items in order. |
1257 // 1. cookie | 1286 // 1. cookie |
1258 // 2. disposition | 1287 // 2. disposition |
1259 // 3. dimension.x | 1288 // 3. dimension.x |
1260 // 4. dimension.y | 1289 // 4. dimension.y |
1261 // 5. dimension.width | 1290 // 5. dimension.width |
1262 // 6. dimension.height. | 1291 // 6. dimension.height. |
1263 if (tokenizer.GetNext()) { | 1292 if (tokenizer.GetNext()) { |
1264 wchar_t* end_ptr = 0; | 1293 wchar_t* end_ptr = 0; |
1265 *cookie = _wcstoui64(tokenizer.token().c_str(), &end_ptr, 10); | 1294 cookie_ = _wcstoui64(tokenizer.token().c_str(), &end_ptr, 10); |
1266 } else { | 1295 } else { |
1267 return false; | 1296 return false; |
1268 } | 1297 } |
1269 | 1298 |
1270 if (tokenizer.GetNext()) { | 1299 if (tokenizer.GetNext()) { |
1271 *disposition = _wtoi(tokenizer.token().c_str()); | 1300 disposition_ = _wtoi(tokenizer.token().c_str()); |
1272 } else { | 1301 } else { |
1273 return false; | 1302 return false; |
1274 } | 1303 } |
1275 | 1304 |
1276 if (tokenizer.GetNext()) { | 1305 if (tokenizer.GetNext()) { |
1277 dimensions->set_x(_wtoi(tokenizer.token().c_str())); | 1306 dimensions_.set_x(_wtoi(tokenizer.token().c_str())); |
1278 } else { | 1307 } else { |
1279 return false; | 1308 return false; |
1280 } | 1309 } |
1281 | 1310 |
1282 if (tokenizer.GetNext()) { | 1311 if (tokenizer.GetNext()) { |
1283 dimensions->set_y(_wtoi(tokenizer.token().c_str())); | 1312 dimensions_.set_y(_wtoi(tokenizer.token().c_str())); |
1284 } else { | 1313 } else { |
1285 return false; | 1314 return false; |
1286 } | 1315 } |
1287 | 1316 |
1288 if (tokenizer.GetNext()) { | 1317 if (tokenizer.GetNext()) { |
1289 dimensions->set_width(_wtoi(tokenizer.token().c_str())); | 1318 dimensions_.set_width(_wtoi(tokenizer.token().c_str())); |
1290 } else { | 1319 } else { |
1291 return false; | 1320 return false; |
1292 } | 1321 } |
1293 | 1322 |
1294 if (tokenizer.GetNext()) { | 1323 if (tokenizer.GetNext()) { |
1295 dimensions->set_height(_wtoi(tokenizer.token().c_str())); | 1324 dimensions_.set_height(_wtoi(tokenizer.token().c_str())); |
1296 } else { | 1325 } else { |
1297 return false; | 1326 return false; |
1298 } | 1327 } |
| 1328 return true; |
| 1329 } |
| 1330 |
| 1331 bool CanNavigateInFullTabMode(const ChromeFrameUrl& cf_url, |
| 1332 IInternetSecurityManager* security_manager) { |
| 1333 bool is_privileged = false; |
| 1334 |
| 1335 if (!IsValidUrlScheme(cf_url.url(), is_privileged)) { |
| 1336 DLOG(WARNING) << __FUNCTION__ << " Disallowing navigation to url: " |
| 1337 << cf_url.url(); |
| 1338 return false; |
| 1339 } |
| 1340 |
| 1341 if (security_manager) { |
| 1342 DWORD zone = URLZONE_INVALID; |
| 1343 security_manager->MapUrlToZone(cf_url.url().c_str(), &zone, 0); |
| 1344 if (zone == URLZONE_UNTRUSTED) { |
| 1345 DLOG(WARNING) << __FUNCTION__ |
| 1346 << " Disallowing navigation to restricted url: " |
| 1347 << cf_url.url(); |
| 1348 return false; |
| 1349 } |
| 1350 } |
| 1351 |
| 1352 if (cf_url.is_chrome_protocol()) { |
| 1353 // Allow chrome protocol (gcf:) if - |
| 1354 // - explicitly enabled using registry |
| 1355 // - for gcf:attach_external_tab |
| 1356 // - for gcf:about and gcf:view-source |
| 1357 GURL crack_url(cf_url.url()); |
| 1358 bool allow_gcf_protocol = |
| 1359 GetConfigBool(false, kEnableGCFProtocol) || |
| 1360 crack_url.SchemeIs(chrome::kAboutScheme) || |
| 1361 crack_url.SchemeIs(chrome::kViewSourceScheme); |
| 1362 if (!allow_gcf_protocol) { |
| 1363 DLOG(WARNING) << __FUNCTION__ |
| 1364 << " Disallowing navigation to gcf url: " |
| 1365 << cf_url.url(); |
| 1366 return false; |
| 1367 } |
| 1368 } |
1299 | 1369 |
1300 return true; | 1370 return true; |
1301 } | 1371 } |
1302 | |
OLD | NEW |