Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | |
michael@0 | 2 | const Cc = Components.classes; |
michael@0 | 3 | const Ci = Components.interfaces; |
michael@0 | 4 | const Cu = Components.utils; |
michael@0 | 5 | const Cr = Components.results; |
michael@0 | 6 | |
michael@0 | 7 | Cu.import('resource://gre/modules/CSPUtils.jsm'); |
michael@0 | 8 | |
michael@0 | 9 | var httpserv = null; |
michael@0 | 10 | |
michael@0 | 11 | const POLICY_FROM_URI = "allow 'self'; img-src *"; |
michael@0 | 12 | const POLICY_PORT = 9000; |
michael@0 | 13 | const POLICY_URI = "http://localhost:" + POLICY_PORT + "/policy"; |
michael@0 | 14 | const POLICY_URI_RELATIVE = "/policy"; |
michael@0 | 15 | const DOCUMENT_URI = "http://localhost:" + POLICY_PORT + "/document"; |
michael@0 | 16 | const CSP_DOC_BODY = "CSP doc content"; |
michael@0 | 17 | const SD = CSPRep.SRC_DIRECTIVES; |
michael@0 | 18 | |
michael@0 | 19 | // this will get populated by run_tests() |
michael@0 | 20 | var TESTS = []; |
michael@0 | 21 | |
michael@0 | 22 | // helper to make URIs |
michael@0 | 23 | function mkuri(foo) { |
michael@0 | 24 | return Cc["@mozilla.org/network/io-service;1"] |
michael@0 | 25 | .getService(Ci.nsIIOService) |
michael@0 | 26 | .newURI(foo, null, null); |
michael@0 | 27 | } |
michael@0 | 28 | |
michael@0 | 29 | // helper to use .equals on stuff |
michael@0 | 30 | function do_check_equivalent(foo, bar, stack) { |
michael@0 | 31 | if (!stack) |
michael@0 | 32 | stack = Components.stack.caller; |
michael@0 | 33 | |
michael@0 | 34 | var text = foo + ".equals(" + bar + ")"; |
michael@0 | 35 | |
michael@0 | 36 | if (foo.equals && foo.equals(bar)) { |
michael@0 | 37 | dump("TEST-PASS | " + stack.filename + " | [" + stack.name + " : " + |
michael@0 | 38 | stack.lineNumber + "] " + text + "\n"); |
michael@0 | 39 | return; |
michael@0 | 40 | } |
michael@0 | 41 | do_throw(text, stack); |
michael@0 | 42 | } |
michael@0 | 43 | |
michael@0 | 44 | function listener(csp, cspr_static) { |
michael@0 | 45 | this.buffer = ""; |
michael@0 | 46 | this._csp = csp; |
michael@0 | 47 | this._cspr_static = cspr_static; |
michael@0 | 48 | } |
michael@0 | 49 | |
michael@0 | 50 | listener.prototype = { |
michael@0 | 51 | onStartRequest: function (request, ctx) { |
michael@0 | 52 | }, |
michael@0 | 53 | |
michael@0 | 54 | onDataAvailable: function (request, ctx, stream, offset, count) { |
michael@0 | 55 | var sInputStream = Cc["@mozilla.org/scriptableinputstream;1"] |
michael@0 | 56 | .createInstance(Ci.nsIScriptableInputStream); |
michael@0 | 57 | sInputStream.init(stream); |
michael@0 | 58 | this.buffer = this.buffer.concat(sInputStream.read(count)); |
michael@0 | 59 | }, |
michael@0 | 60 | |
michael@0 | 61 | onStopRequest: function (request, ctx, status) { |
michael@0 | 62 | // make sure that we have the full document content, guaranteeing that |
michael@0 | 63 | // the document channel has been resumed, before we do the comparisons |
michael@0 | 64 | if (this.buffer == CSP_DOC_BODY) { |
michael@0 | 65 | |
michael@0 | 66 | // need to re-grab cspr since it may have changed inside the document's |
michael@0 | 67 | // nsIContentSecurityPolicy instance. The problem is, this cspr_str is a |
michael@0 | 68 | // string and not a policy due to the way it's exposed from |
michael@0 | 69 | // nsIContentSecurityPolicy, so we have to re-parse it. |
michael@0 | 70 | let cspr_str = this._csp.getPolicy(0); |
michael@0 | 71 | let cspr = CSPRep.fromString(cspr_str, mkuri(DOCUMENT_URI)); |
michael@0 | 72 | |
michael@0 | 73 | // and in reparsing it, we lose the 'self' relationships, so need to also |
michael@0 | 74 | // reparse the static one (or find a way to resolve 'self' in the parsed |
michael@0 | 75 | // policy when doing comparisons). |
michael@0 | 76 | let cspr_static_str = this._cspr_static.toString(); |
michael@0 | 77 | let cspr_static_reparse = CSPRep.fromString(cspr_static_str, mkuri(DOCUMENT_URI)); |
michael@0 | 78 | |
michael@0 | 79 | // not null, and one policy .equals the other one |
michael@0 | 80 | do_check_neq(null, cspr); |
michael@0 | 81 | do_check_true(cspr.equals(cspr_static_reparse)); |
michael@0 | 82 | |
michael@0 | 83 | // final teardown |
michael@0 | 84 | if (TESTS.length == 0) { |
michael@0 | 85 | httpserv.stop(do_test_finished); |
michael@0 | 86 | } else { |
michael@0 | 87 | do_test_finished(); |
michael@0 | 88 | (TESTS.shift())(); |
michael@0 | 89 | } |
michael@0 | 90 | } |
michael@0 | 91 | } |
michael@0 | 92 | }; |
michael@0 | 93 | |
michael@0 | 94 | function run_test() { |
michael@0 | 95 | httpserv = new HttpServer(); |
michael@0 | 96 | httpserv.registerPathHandler("/document", csp_doc_response); |
michael@0 | 97 | httpserv.registerPathHandler("/policy", csp_policy_response); |
michael@0 | 98 | httpserv.start(POLICY_PORT); |
michael@0 | 99 | TESTS = [ test_CSPRep_fromPolicyURI, test_CSPRep_fromRelativePolicyURI ]; |
michael@0 | 100 | |
michael@0 | 101 | // when this triggers the "onStopRequest" callback, it'll |
michael@0 | 102 | // go to the next test. |
michael@0 | 103 | (TESTS.shift())(); |
michael@0 | 104 | } |
michael@0 | 105 | |
michael@0 | 106 | function makeChan(url) { |
michael@0 | 107 | var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); |
michael@0 | 108 | var chan = ios.newChannel(url, null, null).QueryInterface(Ci.nsIHttpChannel); |
michael@0 | 109 | return chan; |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | function csp_doc_response(metadata, response) { |
michael@0 | 113 | response.setStatusLine(metadata.httpVersion, 200, "OK"); |
michael@0 | 114 | response.setHeader("Content-Type", "text/html", false); |
michael@0 | 115 | response.bodyOutputStream.write(CSP_DOC_BODY, CSP_DOC_BODY.length); |
michael@0 | 116 | } |
michael@0 | 117 | |
michael@0 | 118 | function csp_policy_response(metadata, response) { |
michael@0 | 119 | response.setStatusLine(metadata.httpVersion, 200, "OK"); |
michael@0 | 120 | response.setHeader("Content-Type", "text/csp", false); |
michael@0 | 121 | response.bodyOutputStream.write(POLICY_FROM_URI, POLICY_FROM_URI.length); |
michael@0 | 122 | } |
michael@0 | 123 | |
michael@0 | 124 | ///////////////////// TEST POLICY_URI ////////////////////// |
michael@0 | 125 | function test_CSPRep_fromPolicyURI() { |
michael@0 | 126 | do_test_pending(); |
michael@0 | 127 | let csp = Cc["@mozilla.org/contentsecuritypolicy;1"] |
michael@0 | 128 | .createInstance(Ci.nsIContentSecurityPolicy); |
michael@0 | 129 | // once the policy-uri is returned we will compare our static CSPRep with one |
michael@0 | 130 | // we generated from the content we got back from the network to make sure |
michael@0 | 131 | // they are equivalent |
michael@0 | 132 | let cspr_static = CSPRep.fromString(POLICY_FROM_URI, mkuri(DOCUMENT_URI)); |
michael@0 | 133 | |
michael@0 | 134 | // simulates the request for the parent document |
michael@0 | 135 | var docChan = makeChan(DOCUMENT_URI); |
michael@0 | 136 | docChan.asyncOpen(new listener(csp, cspr_static), null); |
michael@0 | 137 | |
michael@0 | 138 | // the resulting policy here can be discarded, since it's going to be |
michael@0 | 139 | // "allow *"; when the policy-uri fetching call-back happens, the *real* |
michael@0 | 140 | // policy will be in csp.policy |
michael@0 | 141 | CSPRep.fromString("policy-uri " + POLICY_URI, |
michael@0 | 142 | mkuri(DOCUMENT_URI), false, docChan, csp); |
michael@0 | 143 | } |
michael@0 | 144 | |
michael@0 | 145 | function test_CSPRep_fromRelativePolicyURI() { |
michael@0 | 146 | do_test_pending(); |
michael@0 | 147 | let csp = Cc["@mozilla.org/contentsecuritypolicy;1"] |
michael@0 | 148 | .createInstance(Ci.nsIContentSecurityPolicy); |
michael@0 | 149 | // once the policy-uri is returned we will compare our static CSPRep with one |
michael@0 | 150 | // we generated from the content we got back from the network to make sure |
michael@0 | 151 | // they are equivalent |
michael@0 | 152 | let cspr_static = CSPRep.fromString(POLICY_FROM_URI, mkuri(DOCUMENT_URI)); |
michael@0 | 153 | |
michael@0 | 154 | // simulates the request for the parent document |
michael@0 | 155 | var docChan = makeChan(DOCUMENT_URI); |
michael@0 | 156 | docChan.asyncOpen(new listener(csp, cspr_static), null); |
michael@0 | 157 | |
michael@0 | 158 | // the resulting policy here can be discarded, since it's going to be |
michael@0 | 159 | // "allow *"; when the policy-uri fetching call-back happens, the *real* |
michael@0 | 160 | // policy will be in csp.policy |
michael@0 | 161 | CSPRep.fromString("policy-uri " + POLICY_URI_RELATIVE, |
michael@0 | 162 | mkuri(DOCUMENT_URI), false, docChan, csp); |
michael@0 | 163 | } |