|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 /* |
|
6 * Description of the test: |
|
7 * We show that we can separate the safebrowsing cookie by creating a custom |
|
8 * LoadContext using a reserved AppId (UINT_32_MAX - 1). Setting this |
|
9 * custom LoadContext as a callback on the channel allows us to query the |
|
10 * AppId and therefore separate the safebrowing cookie in its own cookie-jar. |
|
11 * For testing safebrowsing update we do >> NOT << emulate a response |
|
12 * in the body, rather we only set the cookies in the header of the response |
|
13 * and confirm that cookies are separated in their own cookie-jar. |
|
14 * |
|
15 * 1) We init safebrowsing and simulate an update (cookies are set for localhost) |
|
16 * |
|
17 * 2) We open a channel that should send regular cookies, but not the |
|
18 * safebrowsing cookie. |
|
19 * |
|
20 * 3) We open a channel with a custom callback, simulating a safebrowsing cookie |
|
21 * that should send this simulated safebrowsing cookie as well as the |
|
22 * real safebrowsing cookies. (Confirming that the safebrowsing cookies |
|
23 * actually get stored in the correct jar). |
|
24 */ |
|
25 |
|
26 Cu.import("resource://testing-common/httpd.js"); |
|
27 Cu.import("resource://gre/modules/Services.jsm"); |
|
28 |
|
29 XPCOMUtils.defineLazyGetter(this, "URL", function() { |
|
30 return "http://localhost:" + httpserver.identity.primaryPort; |
|
31 }); |
|
32 |
|
33 XPCOMUtils.defineLazyModuleGetter(this, "SafeBrowsing", |
|
34 "resource://gre/modules/SafeBrowsing.jsm"); |
|
35 |
|
36 var setCookiePath = "/setcookie"; |
|
37 var checkCookiePath = "/checkcookie"; |
|
38 var safebrowsingUpdatePath = "/safebrowsingUpdate"; |
|
39 var httpserver; |
|
40 |
|
41 function inChildProcess() { |
|
42 return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime) |
|
43 .processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; |
|
44 } |
|
45 |
|
46 function cookieSetHandler(metadata, response) { |
|
47 var cookieName = metadata.getHeader("set-cookie"); |
|
48 response.setStatusLine(metadata.httpVersion, 200, "Ok"); |
|
49 response.setHeader("set-Cookie", cookieName + "=1; Path=/", false); |
|
50 response.setHeader("Content-Type", "text/plain"); |
|
51 response.bodyOutputStream.write("Ok", "Ok".length); |
|
52 } |
|
53 |
|
54 function cookieCheckHandler(metadata, response) { |
|
55 var cookies = metadata.getHeader("Cookie"); |
|
56 response.setStatusLine(metadata.httpVersion, 200, "Ok"); |
|
57 response.setHeader("saw-cookies", cookies, false); |
|
58 response.setHeader("Content-Type", "text/plain"); |
|
59 response.bodyOutputStream.write("Ok", "Ok".length); |
|
60 } |
|
61 |
|
62 function safebrowsingUpdateHandler(metadata, response) { |
|
63 var cookieName = "sb-update-cookie"; |
|
64 response.setStatusLine(metadata.httpVersion, 200, "Ok"); |
|
65 response.setHeader("set-Cookie", cookieName + "=1; Path=/", false); |
|
66 response.setHeader("Content-Type", "text/plain"); |
|
67 response.bodyOutputStream.write("Ok", "Ok".length); |
|
68 } |
|
69 |
|
70 function setupChannel(path, loadContext) { |
|
71 var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); |
|
72 var channel = ios.newChannel(URL + path, "", null); |
|
73 channel.notificationCallbacks = loadContext; |
|
74 channel.QueryInterface(Ci.nsIHttpChannel); |
|
75 return channel; |
|
76 } |
|
77 |
|
78 function run_test() { |
|
79 |
|
80 // Set up a profile |
|
81 do_get_profile(); |
|
82 |
|
83 // Allow all cookies if the pref service is available in this process. |
|
84 if (!inChildProcess()) |
|
85 Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); |
|
86 |
|
87 httpserver = new HttpServer(); |
|
88 httpserver.registerPathHandler(setCookiePath, cookieSetHandler); |
|
89 httpserver.registerPathHandler(checkCookiePath, cookieCheckHandler); |
|
90 httpserver.registerPathHandler(safebrowsingUpdatePath, safebrowsingUpdateHandler); |
|
91 |
|
92 httpserver.start(-1); |
|
93 run_next_test(); |
|
94 } |
|
95 |
|
96 // this test does not emulate a response in the body, |
|
97 // rather we only set the cookies in the header of response. |
|
98 add_test(function test_safebrowsing_update() { |
|
99 |
|
100 var dbservice = Cc["@mozilla.org/url-classifier/dbservice;1"] |
|
101 .getService(Ci.nsIUrlClassifierDBService); |
|
102 var streamUpdater = Cc["@mozilla.org/url-classifier/streamupdater;1"] |
|
103 .getService(Ci.nsIUrlClassifierStreamUpdater); |
|
104 |
|
105 streamUpdater.updateUrl = URL + safebrowsingUpdatePath; |
|
106 |
|
107 function onSuccess() { |
|
108 run_next_test(); |
|
109 } |
|
110 function onUpdateError() { |
|
111 do_throw("ERROR: received onUpdateError!"); |
|
112 } |
|
113 function onDownloadError() { |
|
114 do_throw("ERROR: received onDownloadError!"); |
|
115 } |
|
116 |
|
117 streamUpdater.downloadUpdates("test-phish-simple,test-malware-simple", "", |
|
118 onSuccess, onUpdateError, onDownloadError); |
|
119 }); |
|
120 |
|
121 add_test(function test_non_safebrowsing_cookie() { |
|
122 |
|
123 var cookieName = 'regCookie_id0'; |
|
124 var loadContext = new LoadContextCallback(0, false, false, false); |
|
125 |
|
126 function setNonSafeBrowsingCookie() { |
|
127 var channel = setupChannel(setCookiePath, loadContext); |
|
128 channel.setRequestHeader("set-cookie", cookieName, false); |
|
129 channel.asyncOpen(new ChannelListener(checkNonSafeBrowsingCookie, null), null); |
|
130 } |
|
131 |
|
132 function checkNonSafeBrowsingCookie() { |
|
133 var channel = setupChannel(checkCookiePath, loadContext); |
|
134 channel.asyncOpen(new ChannelListener(completeCheckNonSafeBrowsingCookie, null), null); |
|
135 } |
|
136 |
|
137 function completeCheckNonSafeBrowsingCookie(request, data, context) { |
|
138 // Confirm that only the >> ONE << cookie is sent over the channel. |
|
139 var expectedCookie = cookieName + "=1"; |
|
140 request.QueryInterface(Ci.nsIHttpChannel); |
|
141 var cookiesSeen = request.getResponseHeader("saw-cookies"); |
|
142 do_check_eq(cookiesSeen, expectedCookie); |
|
143 run_next_test(); |
|
144 } |
|
145 |
|
146 setNonSafeBrowsingCookie(); |
|
147 }); |
|
148 |
|
149 add_test(function test_safebrowsing_cookie() { |
|
150 |
|
151 var cookieName = 'sbCookie_id4294967294'; |
|
152 var loadContext = new LoadContextCallback(Ci.nsIScriptSecurityManager.SAFEBROWSING_APP_ID, false, false, false); |
|
153 |
|
154 function setSafeBrowsingCookie() { |
|
155 var channel = setupChannel(setCookiePath, loadContext); |
|
156 channel.setRequestHeader("set-cookie", cookieName, false); |
|
157 channel.asyncOpen(new ChannelListener(checkSafeBrowsingCookie, null), null); |
|
158 } |
|
159 |
|
160 function checkSafeBrowsingCookie() { |
|
161 var channel = setupChannel(checkCookiePath, loadContext); |
|
162 channel.asyncOpen(new ChannelListener(completeCheckSafeBrowsingCookie, null), null); |
|
163 } |
|
164 |
|
165 function completeCheckSafeBrowsingCookie(request, data, context) { |
|
166 // Confirm that all >> THREE << cookies are sent back over the channel: |
|
167 // a) the safebrowsing cookie set when updating |
|
168 // b) the regular cookie with custom loadcontext defined in this test. |
|
169 var expectedCookies = "sb-update-cookie=1; "; |
|
170 expectedCookies += cookieName + "=1"; |
|
171 request.QueryInterface(Ci.nsIHttpChannel); |
|
172 var cookiesSeen = request.getResponseHeader("saw-cookies"); |
|
173 |
|
174 do_check_eq(cookiesSeen, expectedCookies); |
|
175 httpserver.stop(do_test_finished); |
|
176 } |
|
177 |
|
178 setSafeBrowsingCookie(); |
|
179 }); |