michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * Description of the test: michael@0: * We show that we can separate the safebrowsing cookie by creating a custom michael@0: * LoadContext using a reserved AppId (UINT_32_MAX - 1). Setting this michael@0: * custom LoadContext as a callback on the channel allows us to query the michael@0: * AppId and therefore separate the safebrowing cookie in its own cookie-jar. michael@0: * For testing safebrowsing update we do >> NOT << emulate a response michael@0: * in the body, rather we only set the cookies in the header of the response michael@0: * and confirm that cookies are separated in their own cookie-jar. michael@0: * michael@0: * 1) We init safebrowsing and simulate an update (cookies are set for localhost) michael@0: * michael@0: * 2) We open a channel that should send regular cookies, but not the michael@0: * safebrowsing cookie. michael@0: * michael@0: * 3) We open a channel with a custom callback, simulating a safebrowsing cookie michael@0: * that should send this simulated safebrowsing cookie as well as the michael@0: * real safebrowsing cookies. (Confirming that the safebrowsing cookies michael@0: * actually get stored in the correct jar). michael@0: */ michael@0: michael@0: Cu.import("resource://testing-common/httpd.js"); michael@0: Cu.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: XPCOMUtils.defineLazyGetter(this, "URL", function() { michael@0: return "http://localhost:" + httpserver.identity.primaryPort; michael@0: }); michael@0: michael@0: XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing", michael@0: "resource://gre/modules/SafeBrowsing.jsm"); michael@0: michael@0: var setCookiePath = "/setcookie"; michael@0: var checkCookiePath = "/checkcookie"; michael@0: var safebrowsingUpdatePath = "/safebrowsingUpdate"; michael@0: var httpserver; michael@0: michael@0: function inChildProcess() { michael@0: return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) michael@0: .processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; michael@0: } michael@0: michael@0: function cookieSetHandler(metadata, response) { michael@0: var cookieName = metadata.getHeader("set-cookie"); michael@0: response.setStatusLine(metadata.httpVersion, 200, "Ok"); michael@0: response.setHeader("set-Cookie", cookieName + "=1; Path=/", false); michael@0: response.setHeader("Content-Type", "text/plain"); michael@0: response.bodyOutputStream.write("Ok", "Ok".length); michael@0: } michael@0: michael@0: function cookieCheckHandler(metadata, response) { michael@0: var cookies = metadata.getHeader("Cookie"); michael@0: response.setStatusLine(metadata.httpVersion, 200, "Ok"); michael@0: response.setHeader("saw-cookies", cookies, false); michael@0: response.setHeader("Content-Type", "text/plain"); michael@0: response.bodyOutputStream.write("Ok", "Ok".length); michael@0: } michael@0: michael@0: function safebrowsingUpdateHandler(metadata, response) { michael@0: var cookieName = "sb-update-cookie"; michael@0: response.setStatusLine(metadata.httpVersion, 200, "Ok"); michael@0: response.setHeader("set-Cookie", cookieName + "=1; Path=/", false); michael@0: response.setHeader("Content-Type", "text/plain"); michael@0: response.bodyOutputStream.write("Ok", "Ok".length); michael@0: } michael@0: michael@0: function setupChannel(path, loadContext) { michael@0: var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); michael@0: var channel = ios.newChannel(URL + path, "", null); michael@0: channel.notificationCallbacks = loadContext; michael@0: channel.QueryInterface(Ci.nsIHttpChannel); michael@0: return channel; michael@0: } michael@0: michael@0: function run_test() { michael@0: michael@0: // Set up a profile michael@0: do_get_profile(); michael@0: michael@0: // Allow all cookies if the pref service is available in this process. michael@0: if (!inChildProcess()) michael@0: Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); michael@0: michael@0: httpserver = new HttpServer(); michael@0: httpserver.registerPathHandler(setCookiePath, cookieSetHandler); michael@0: httpserver.registerPathHandler(checkCookiePath, cookieCheckHandler); michael@0: httpserver.registerPathHandler(safebrowsingUpdatePath, safebrowsingUpdateHandler); michael@0: michael@0: httpserver.start(-1); michael@0: run_next_test(); michael@0: } michael@0: michael@0: // this test does not emulate a response in the body, michael@0: // rather we only set the cookies in the header of response. michael@0: add_test(function test_safebrowsing_update() { michael@0: michael@0: var dbservice = Cc["@mozilla.org/url-classifier/dbservice;1"] michael@0: .getService(Ci.nsIUrlClassifierDBService); michael@0: var streamUpdater = Cc["@mozilla.org/url-classifier/streamupdater;1"] michael@0: .getService(Ci.nsIUrlClassifierStreamUpdater); michael@0: michael@0: streamUpdater.updateUrl = URL + safebrowsingUpdatePath; michael@0: michael@0: function onSuccess() { michael@0: run_next_test(); michael@0: } michael@0: function onUpdateError() { michael@0: do_throw("ERROR: received onUpdateError!"); michael@0: } michael@0: function onDownloadError() { michael@0: do_throw("ERROR: received onDownloadError!"); michael@0: } michael@0: michael@0: streamUpdater.downloadUpdates("test-phish-simple,test-malware-simple", "", michael@0: onSuccess, onUpdateError, onDownloadError); michael@0: }); michael@0: michael@0: add_test(function test_non_safebrowsing_cookie() { michael@0: michael@0: var cookieName = 'regCookie_id0'; michael@0: var loadContext = new LoadContextCallback(0, false, false, false); michael@0: michael@0: function setNonSafeBrowsingCookie() { michael@0: var channel = setupChannel(setCookiePath, loadContext); michael@0: channel.setRequestHeader("set-cookie", cookieName, false); michael@0: channel.asyncOpen(new ChannelListener(checkNonSafeBrowsingCookie, null), null); michael@0: } michael@0: michael@0: function checkNonSafeBrowsingCookie() { michael@0: var channel = setupChannel(checkCookiePath, loadContext); michael@0: channel.asyncOpen(new ChannelListener(completeCheckNonSafeBrowsingCookie, null), null); michael@0: } michael@0: michael@0: function completeCheckNonSafeBrowsingCookie(request, data, context) { michael@0: // Confirm that only the >> ONE << cookie is sent over the channel. michael@0: var expectedCookie = cookieName + "=1"; michael@0: request.QueryInterface(Ci.nsIHttpChannel); michael@0: var cookiesSeen = request.getResponseHeader("saw-cookies"); michael@0: do_check_eq(cookiesSeen, expectedCookie); michael@0: run_next_test(); michael@0: } michael@0: michael@0: setNonSafeBrowsingCookie(); michael@0: }); michael@0: michael@0: add_test(function test_safebrowsing_cookie() { michael@0: michael@0: var cookieName = 'sbCookie_id4294967294'; michael@0: var loadContext = new LoadContextCallback(Ci.nsIScriptSecurityManager.SAFEBROWSING_APP_ID, false, false, false); michael@0: michael@0: function setSafeBrowsingCookie() { michael@0: var channel = setupChannel(setCookiePath, loadContext); michael@0: channel.setRequestHeader("set-cookie", cookieName, false); michael@0: channel.asyncOpen(new ChannelListener(checkSafeBrowsingCookie, null), null); michael@0: } michael@0: michael@0: function checkSafeBrowsingCookie() { michael@0: var channel = setupChannel(checkCookiePath, loadContext); michael@0: channel.asyncOpen(new ChannelListener(completeCheckSafeBrowsingCookie, null), null); michael@0: } michael@0: michael@0: function completeCheckSafeBrowsingCookie(request, data, context) { michael@0: // Confirm that all >> THREE << cookies are sent back over the channel: michael@0: // a) the safebrowsing cookie set when updating michael@0: // b) the regular cookie with custom loadcontext defined in this test. michael@0: var expectedCookies = "sb-update-cookie=1; "; michael@0: expectedCookies += cookieName + "=1"; michael@0: request.QueryInterface(Ci.nsIHttpChannel); michael@0: var cookiesSeen = request.getResponseHeader("saw-cookies"); michael@0: michael@0: do_check_eq(cookiesSeen, expectedCookies); michael@0: httpserver.stop(do_test_finished); michael@0: } michael@0: michael@0: setSafeBrowsingCookie(); michael@0: });