| 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 |