tbb-commits
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 1 participants
- 21316 discussions
[torbutton/master] Merge remote-tracking branch 'gk/bug_9387_test_02'
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit bd5be6801b3bd2ac19e9f7dad98f229d32a82224
Merge: 2c2c5a8 cda1d6c
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Thu Oct 30 15:17:59 2014 -0700
Merge remote-tracking branch 'gk/bug_9387_test_02'
src/chrome/content/preferences.js | 37 +++++++
src/chrome/content/preferences.xul | 62 +++++++++--
src/chrome/content/torbutton.js | 177 +++++++++++++++++++++++++++++++
src/chrome/locale/en/torbutton.dtd | 9 +-
src/defaults/preferences/preferences.js | 3 +
5 files changed, 276 insertions(+), 12 deletions(-)
1
0
[torbutton/master] Bug #8641: TorButton popup menu that displays current Tor circuit
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit 2c2c5a8aceae44c68915e8fe33bc3865f00b535c
Author: Arthur Edelstein <arthuredelstein(a)gmail.com>
Date: Fri Aug 1 23:28:06 2014 -0700
Bug #8641: TorButton popup menu that displays current Tor circuit
---
src/chrome.manifest | 3 +-
src/chrome/content/popup.xul | 33 +-
src/chrome/content/tor-circuit-display.js | 185 ++++++++++
src/chrome/content/torbutton.js | 2 +
src/chrome/content/torbutton.xul | 1 +
src/chrome/skin/torbutton.css | 15 +
src/modules/tor-control-port.js | 575 +++++++++++++++++++++++++++++
7 files changed, 809 insertions(+), 5 deletions(-)
diff --git a/src/chrome.manifest b/src/chrome.manifest
index d211984..2ab3c8f 100644
--- a/src/chrome.manifest
+++ b/src/chrome.manifest
@@ -3,6 +3,7 @@ overlay chrome://browser/content/browser.xul chrome://torbutton/content/torbutto
overlay chrome://browser/content/preferences/connection.xul chrome://torbutton/content/pref-connection.xul
overlay chrome://messenger/content/messenger.xul chrome://torbutton/content/torbutton_tb.xul
overlay chrome://messenger/content/messengercompose/messengercompose.xul chrome://torbutton/content/torbutton_tb.xul
+resource torbutton ./
# browser branding
override chrome://branding/locale/brand.dtd chrome://torbutton/locale/brand.dtd
@@ -161,4 +162,4 @@ contract @torproject.org/domain-isolator;1 {e33fd6d4-270f-475f-a96f-ff3140279f68
category profile-after-change CookieJarSelector @torproject.org/cookie-jar-selector;1
category profile-after-change TBSessionBlocker @torproject.org/torbutton-ss-blocker;1
category profile-after-change StartupObserver @torproject.org/startup-observer;1
-category profile-after-change DomainIsolator @torproject.org/domain-isolator;1
\ No newline at end of file
+category profile-after-change DomainIsolator @torproject.org/domain-isolator;1
diff --git a/src/chrome/content/popup.xul b/src/chrome/content/popup.xul
index 3ee953b..2965ec5 100644
--- a/src/chrome/content/popup.xul
+++ b/src/chrome/content/popup.xul
@@ -9,14 +9,16 @@
<stringbundleset id="torbutton-stringbundleset">
<stringbundle id="torbutton-bundle" src="chrome://torbutton/locale/torbutton.properties"/>
</stringbundleset>
- <menupopup id="torbutton-context-menu" onpopupshowing="torbutton_check_protections();"
- anchor="torbutton-button" position="after_start">
+ <panel id="torbutton-context-menu" onpopupshowing="torbutton_check_protections();" titlebar="normal" noautohide="true"
+ anchor="torbutton-button" position="after_start" >
+ <hbox align="start">
+ <vbox>
<menuitem id="torbutton-new-identity"
label="&torbutton.context_menu.new_identity;"
accesskey="&torbutton.context_menu.new_identity_key;"
insertafter="context-stop"
oncommand="torbutton_new_identity()"/>
- <menuitem id="torbutton-cookie-protector"
+ <menuitem id="torbutton-cookie-protector"
label="&torbutton.context_menu.cookieProtections;"
accesskey="&torbutton.context_menu.cookieProtections.key;"
insertafter="context-stop"
@@ -42,6 +44,29 @@
insertafter="context-stop"
oncommand="torbutton_download_update()"
hidden="true"/>
- </menupopup>
+ </vbox>
+ <vbox>
+ <!-- The following SVG is used to display a Tor circuit diagram for the current tab.
+ It is not displayed unless activated by tor-circuit-display.js. -->
+ <svg xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="full"
+ width="290" height="140" id="tor-circuit" style="display:none;">
+ <rect x="0" y="0" width="100%" height="100%" fill="#e8f4f4" />
+ <text id="title" style="font-size:14px;font-weight:bold;" x="10" y="20" fill="#2c26a7">Tor circuit for this site</text>
+ <text id="domain" style="font-size:13px;" x="10" y="38" fill="black">(trac.torproject.org)</text>
+ <rect x="18.5" width="3" y="56" height="64" fill="#4d363a" stroke-width="0"/>
+ <circle class="node-circle" cx="20" cy="56" r="4" />
+ <text class="node-text" x="32" y="56">This Browser</text>
+ <circle class="node-circle" cx="20" cy="72" r="4" />
+ <text class="node-text" x="32" y="72">Test123 (54.67.87.34)</text>
+ <circle class="node-circle" cx="20" cy="88" r="4" />
+ <text class="node-text" x="32" y="88">TestABC (121.4.56.67)</text>
+ <circle class="node-circle" cx="20" cy="104" r="4" />
+ <text class="node-text" x="32" y="104">TestXYZ (74.3.30.9)</text>
+ <circle class="node-circle" cx="20" cy="120" r="4" />
+ <text class="node-text" x="32" y="120">Internet</text>
+ </svg>
+ </vbox>
+ </hbox>
+ </panel>
</overlay>
diff --git a/src/chrome/content/tor-circuit-display.js b/src/chrome/content/tor-circuit-display.js
new file mode 100644
index 0000000..5f4d8bf
--- /dev/null
+++ b/src/chrome/content/tor-circuit-display.js
@@ -0,0 +1,185 @@
+// A script that automatically displays the Tor Circuit used for the
+// current domain for the currently selected tab.
+//
+// This file is written in call stack order (later functions
+// call earlier functions). The file can be processed
+// with docco.js to produce pretty documentation.
+//
+// This script is to be embedded in torbutton.xul. It defines a single global function,
+// runTorCircuitDisplay(host, port, password), which activates the automatic Tor
+// circuit display for the current tab and any future tabs.
+//
+// See https://trac.torproject.org/8641
+
+/* jshint esnext: true */
+/* global document, gBrowser, Components */
+
+// ### Main function
+// __runTorCircuitDisplay(host, port, password)__.
+// The single function we run to activate automatic display of the Tor circuit..
+let runTorCircuitDisplay = (function () {
+
+"use strict";
+
+// Mozilla utilities
+const Cu = Components.utils;
+Cu.import("resource://gre/modules/Services.jsm");
+
+// Import the controller code.
+let { controller } = Cu.import("resource://torbutton/modules/tor-control-port.js");
+
+// Make the TorButton logger available.
+let logger = Cc["@torproject.org/torbutton-logger;1"]
+ .getService(Components.interfaces.nsISupports).wrappedJSObject;
+
+// __regionBundle__.
+// A list of localized region (country) names.
+let regionBundle = Services.strings.createBundle(
+ "chrome://global/locale/regionNames.properties");
+
+// __localizedCountryNameFromCode(countryCode)__.
+// Convert a country code to a localized country name.
+// Example: `'de'` -> `'Deutschland'` in German locale.
+let localizedCountryNameFromCode = function (countryCode) {
+ try {
+ return regionBundle.GetStringFromName(countryCode.toLowerCase());
+ } catch (e) {
+ return countryCode.toUpperCase();
+ }
+};
+
+// __domainToNodeDataMap__.
+// A mutable map that stores the current nodes for each domain.
+let domainToNodeDataMap = {};
+
+// __trimQuotes(s)__.
+// Removes quotation marks around a quoted string.
+let trimQuotes = s => s.match(/^\"(.*)\"$/)[1];
+
+// nodeDataForID(controller, id, onResult)__.
+// Requests the IP, country code, and name of a node with given ID.
+// Returns result via onResult.
+// Example: nodeData(["20BC91DC525C3DC9974B29FBEAB51230DE024C44"], show);
+let nodeDataForID = function (controller, ids, onResult) {
+ let idRequests = ids.map(id => "ns/id/" + id);
+ controller.getInfoMultiple(idRequests, function (statusMaps) {
+ let IPs = statusMaps.map(statusMap => statusMap.IP),
+ countryRequests = IPs.map(ip => "ip-to-country/" + ip);
+ controller.getInfoMultiple(countryRequests, function (countries) {
+ let results = [];
+ for (let i = 0; i < ids.length; ++i) {
+ results.push({ name : statusMaps[i].nickname, id : ids[i] ,
+ ip : statusMaps[i].IP , country : countries[i] });
+ }
+ onResult(results);
+ });
+ });
+};
+
+// __nodeDataForCircuit(controller, circuitEvent, onResult)__.
+// Gets the information for a circuit.
+let nodeDataForCircuit = function (controller, circuitEvent, onResult) {
+ let ids = circuitEvent.circuit.map(circ => circ[0]);
+ nodeDataForID(controller, ids, onResult);
+};
+
+// __nodeLines(nodeData)__.
+// Takes a nodeData array of three items each like
+// `{ ip : "12.34.56.78", country : "fr" }`
+// and converts each node data to text, as
+// `"France (12.34.56.78)"`.
+let nodeLines = function (nodeData) {
+ let result = ["This browser"];
+ for (let {ip, country} of nodeData) {
+ result.push(localizedCountryNameFromCode(country) + " (" + ip + ")");
+ }
+ result.push("Internet");
+ return result;
+};
+
+// __updateCircuitDisplay()__.
+// Updates the Tor circuit display SVG, showing the current domain
+// and the relay nodes for that domain.
+let updateCircuitDisplay = function () {
+ let URI = gBrowser.selectedBrowser.currentURI,
+ domain = null,
+ nodeData = null;
+ // Try to get a domain for this URI. Otherwise it remains null.
+ try {
+ domain = URI.host;
+ } catch (e) { }
+ if (domain) {
+ // Check if we have anything to show for this domain.
+ nodeData = domainToNodeDataMap[domain];
+ if (nodeData) {
+ // Update the displayed domain.
+ document.querySelector("svg#tor-circuit text#domain").innerHTML = "(" + domain + "):";
+ // Update the displayed information for the relay nodes.
+ let diagramNodes = document.querySelectorAll("svg#tor-circuit text.node-text"),
+ lines = nodeLines(nodeData);
+ for (let i = 0; i < diagramNodes.length; ++i) {
+ diagramNodes[i].innerHTML = lines[i];
+ }
+ }
+ }
+ // Only show the Tor circuit if we have a domain and node data.
+ document.querySelector("svg#tor-circuit").style.display = (domain && nodeData) ?
+ 'block' : 'none';
+};
+
+// __collectBuiltCircuitData(aController)__.
+// Watches for CIRC BUILT events and records their data in the domainToNodeDataMap.
+let collectBuiltCircuitData = function (aController) {
+ aController.watchEvent(
+ "CIRC",
+ circuitEvent => circuitEvent.status === "EXTENDED" ||
+ circuitEvent.status === "BUILT",
+ function (circuitEvent) {
+ let domain = trimQuotes(circuitEvent.SOCKS_USERNAME);
+ if (domain) {
+ nodeDataForCircuit(aController, circuitEvent, function (nodeData) {
+ domainToNodeDataMap[domain] = nodeData;
+ updateCircuitDisplay();
+ });
+ } else {
+ updateCircuitDisplay();
+ }
+ });
+};
+
+// __syncDisplayWithSelectedTab()__.
+// We may have multiple tabs, but there is only one instance of TorButton's popup
+// panel for displaying the Tor circuit UI. Therefore we need to update the display
+// to show the currently selected tab at its current location.
+let syncDisplayWithSelectedTab = function () {
+ // Whenever a different tab is selected, change the circuit display
+ // to show the circuit for that tab's domain.
+ gBrowser.tabContainer.addEventListener("TabSelect", function (event) {
+ updateCircuitDisplay();
+ });
+ // If the currently selected tab has been sent to a new location,
+ // update the circuit to reflect that.
+ gBrowser.addTabsProgressListener({ onLocationChange : function (aBrowser) {
+ if (aBrowser == gBrowser.selectedBrowser) {
+ updateCircuitDisplay();
+ }
+ } });
+
+ // Get started with a correct display.
+ updateCircuitDisplay();
+};
+
+// __display(host, port, password)__.
+// The main function for activating automatic display of the Tor circuit.
+// A reference to this function (called runTorCircuitDisplay) is exported as a global.
+let display = function (host, port, password) {
+ let myController = controller(host, port || 9151, password, function (x) { logger.eclog(5, x); });
+ syncDisplayWithSelectedTab();
+ collectBuiltCircuitData(myController);
+};
+
+return display;
+
+// Finish runTorCircuitDisplay()
+})();
+
diff --git a/src/chrome/content/torbutton.js b/src/chrome/content/torbutton.js
index 7fddf07..5be2c6d 100644
--- a/src/chrome/content/torbutton.js
+++ b/src/chrome/content/torbutton.js
@@ -578,6 +578,8 @@ function torbutton_init() {
torbutton_update_statusbar(mode);
torbutton_notify_if_update_needed();
+ runTorCircuitDisplay(m_tb_control_host, m_tb_control_port, m_tb_control_pass);
+
torbutton_log(3, 'init completed');
}
diff --git a/src/chrome/content/torbutton.xul b/src/chrome/content/torbutton.xul
index 9e10b09..00dc6f0 100644
--- a/src/chrome/content/torbutton.xul
+++ b/src/chrome/content/torbutton.xul
@@ -11,6 +11,7 @@
<script src="chrome://torbutton/content/stanford-safecache.js" />
<script type="application/x-javascript" src="chrome://torbutton/content/torbutton_util.js" />
+ <script type="application/x-javascript" src="chrome://torbutton/content/tor-circuit-display.js" />
<script type="application/x-javascript" src="chrome://torbutton/content/torbutton.js" />
<script language="JavaScript">
//onLoad Hander
diff --git a/src/chrome/skin/torbutton.css b/src/chrome/skin/torbutton.css
index ef8abbc..f368c9c 100644
--- a/src/chrome/skin/torbutton.css
+++ b/src/chrome/skin/torbutton.css
@@ -104,3 +104,18 @@ statusbarpanel#plugins-status[status="0"] {
#torbutton-downloadUpdate {
font-weight: bold;
}
+
+svg.circuit text {
+ font-family: Arial;
+}
+
+svg#tor-circuit text.node-text {
+ dominant-baseline: central;
+ font-size: 14px;
+}
+
+svg#tor-circuit circle.node-circle {
+ stroke: #195021;
+ stroke-width: 2px;
+ fill: white;
+}
\ No newline at end of file
diff --git a/src/modules/tor-control-port.js b/src/modules/tor-control-port.js
new file mode 100644
index 0000000..2f993d7
--- /dev/null
+++ b/src/modules/tor-control-port.js
@@ -0,0 +1,575 @@
+// A module for TorBrowser that provides an asynchronous controller for
+// Tor, through its ControlPort.
+//
+// This file is written in call stack order (later functions
+// call earlier functions). The file can be processed
+// with docco.js to produce pretty documentation.
+//
+// To import the module, use
+//
+// let { controller } = Components.utils.import("path/to/controlPort.jsm");
+//
+// See the last function defined in this file, controller(host, port, password, onError)
+// for usage of the controller function.
+
+/* jshint esnext: true */
+/* jshint -W097 */
+/* global Components, console */
+"use strict";
+
+// ### Mozilla Abbreviations
+let {classes: Cc, interfaces: Ci, results: Cr, Constructor: CC, utils: Cu } = Components;
+
+// ## io
+// I/O utilities namespace
+let io = io || {};
+
+// __io.asyncSocketStreams(host, port)__.
+// Creates a pair of asynchronous input and output streams for a socket at the
+// given host and port.
+io.asyncSocketStreams = function (host, port) {
+ let socketTransportService = Cc["@mozilla.org/network/socket-transport-service;1"]
+ .getService(Components.interfaces.nsISocketTransportService),
+ BLOCKING = Ci.nsITransport.OPEN_BLOCKING,
+ UNBUFFERED = Ci.nsITransport.OPEN_UNBUFFERED,
+ // Create an instance of a socket transport.
+ socketTransport = socketTransportService.createTransport(null, 0, host, port, null),
+ // Open unbuffered synchronous outputStream.
+ outputStream = socketTransport.openOutputStream(BLOCKING | UNBUFFERED, 1, 1),
+ // Open unbuffered asynchronous inputStream.
+ inputStream = socketTransport.openInputStream(UNBUFFERED, 1, 1)
+ .QueryInterface(Ci.nsIAsyncInputStream);
+ return [inputStream, outputStream];
+};
+
+// __io.pumpInputStream(scriptableInputStream, onInputData, onError)__.
+// Run an "input stream pump" that takes an input stream and
+// asynchronously pumps incoming data to the onInputData callback.
+io.pumpInputStream = function (inputStream, onInputData, onError) {
+ // Wrap raw inputStream with a "ScriptableInputStream" so we can read incoming data.
+ let ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1",
+ "nsIScriptableInputStream", "init"),
+ scriptableInputStream = new ScriptableInputStream(inputStream),
+ // A private method to read all data available on the input stream.
+ readAll = function() {
+ return scriptableInputStream.read(scriptableInputStream.available());
+ },
+ pump = Cc["@mozilla.org/network/input-stream-pump;1"]
+ .createInstance(Components.interfaces.nsIInputStreamPump);
+ // Start the pump.
+ pump.init(inputStream, -1, -1, 0, 0, true);
+ // Tell the pump to read all data whenever it is available, and pass the data
+ // to the onInputData callback. The first argument to asyncRead implements
+ // nsIStreamListener.
+ pump.asyncRead({ onStartRequest: function (request, context) { },
+ onStopRequest: function (request, context, code) { },
+ onDataAvailable : function (request, context, stream, offset, count) {
+ try {
+ onInputData(readAll());
+ } catch (error) {
+ // readAll() or onInputData(...) has thrown an error.
+ // Notify calling code through onError.
+ onError(error);
+ }
+ } }, null);
+};
+
+// __io.asyncSocket(host, port, onInputData, onError)__.
+// Creates an asynchronous, text-oriented TCP socket at host:port.
+// The onInputData callback should accept a single argument, which will be called
+// repeatedly, whenever incoming text arrives. Returns a socket object with two methods:
+// socket.write(text) and socket.close(). onError will be passed the error object
+// whenever a write fails.
+io.asyncSocket = function (host, port, onInputData, onError) {
+ let [inputStream, outputStream] = io.asyncSocketStreams(host, port);
+ // Run an input stream pump to send incoming data to the onInputData callback.
+ io.pumpInputStream(inputStream, onInputData, onError);
+ return {
+ // Write a message to the socket.
+ write : function(aString) {
+ try {
+ outputStream.write(aString, aString.length);
+ // console.log(aString);
+ } catch (err) {
+ // This write() method is not necessarily called by a callback,
+ // but we pass any thrown errors to onError to ensure the socket
+ // error handling uses a consistent single path.
+ onError(err);
+ }
+ },
+ // Close the socket.
+ close : function () {
+ // Close stream objects.
+ inputStream.close();
+ outputStream.close();
+ }
+ };
+};
+
+// __io.onDataFromOnLine(onLine)__.
+// Converts a callback that expects incoming individual lines of text to a callback that
+// expects incoming raw socket string data.
+io.onDataFromOnLine = function (onLine) {
+ // A private variable that stores the last unfinished line.
+ let pendingData = "";
+ // Return a callback to be passed to io.asyncSocket. First, splits data into lines of
+ // text. If the incoming data is not terminated by CRLF, then the last
+ // unfinished line will be stored in pendingData, to be prepended to the data in the
+ // next call to onData. The already complete lines of text are then passed in sequence
+ // to onLine.
+ return function (data) {
+ let totalData = pendingData + data,
+ lines = totalData.split("\r\n"),
+ n = lines.length;
+ pendingData = lines[n - 1];
+ // Call onLine for all completed lines.
+ lines.slice(0,-1).map(onLine);
+ };
+};
+
+// __io.onLineFromOnMessage(onMessage)__.
+// Converts a callback that expects incoming control port multiline message strings to a
+// callback that expects individual lines.
+io.onLineFromOnMessage = function (onMessage) {
+ // A private variable that stores the last unfinished line.
+ let pendingLines = [];
+ // Return a callback that expects individual lines.
+ return function (line) {
+ // Add to the list of pending lines.
+ pendingLines.push(line);
+ // If line is the last in a message, then pass on the full multiline message.
+ if (line.match(/^\d\d\d /) && (pendingLines.length == 1 ||
+ pendingLines[0].startsWith(line.substring(0,3)))) {
+ // Combine pending lines to form message.
+ let message = pendingLines.join("\r\n");
+ // Wipe pendingLines before we call onMessage, in case onMessage throws an error.
+ pendingLines = [];
+ // Pass multiline message to onMessage.
+ onMessage(message);
+ // console.log(message);
+ }
+ };
+};
+
+// __io.callbackDispatcher()__.
+// Returns [onString, dispatcher] where the latter is an object with two member functions:
+// dispatcher.addCallback(regex, callback), and dispatcher.removeCallback(callback).
+// Pass onString to another function that needs a callback with a single string argument.
+// Whenever dispatcher.onString receives a string, the dispatcher will check for any
+// regex matches and pass the string on to the corresponding callback(s).
+io.callbackDispatcher = function () {
+ let callbackPairs = [],
+ removeCallback = function (aCallback) {
+ callbackPairs = callbackPairs.filter(function ([regex, callback]) {
+ return callback !== aCallback;
+ });
+ },
+ addCallback = function (regex, callback) {
+ if (callback) {
+ callbackPairs.push([regex, callback]);
+ }
+ return function () { removeCallback(callback); };
+ },
+ onString = function (message) {
+ for (let [regex, callback] of callbackPairs) {
+ if (message.match(regex)) {
+ callback(message);
+ }
+ }
+ };
+ return [onString, {addCallback : addCallback, removeCallback : removeCallback}];
+};
+
+// __io.matchRepliesToCommands(asyncSend)__.
+// Takes asyncSend(message), an asynchronous send function, and returns two functions
+// sendCommand(command, replyCallback) and onReply(response). If we call sendCommand,
+// then when onReply is called, the corresponding replyCallback will be called.
+io.matchRepliesToCommands = function (asyncSend) {
+ let commandQueue = [],
+ sendCommand = function (command, replyCallback) {
+ commandQueue.push([command, replyCallback]);
+ asyncSend(command);
+ },
+ onReply = function (reply) {
+ let [command, replyCallback] = commandQueue.shift();
+ if (replyCallback) { replyCallback(reply); }
+ },
+ onFailure = function () {
+ commandQueue.shift();
+ };
+ return [sendCommand, onReply, onFailure];
+};
+
+// __io.controlSocket(host, port, password, onError)__.
+// Instantiates and returns a socket to a tor ControlPort at host:port,
+// authenticating with the given password. onError is called with an
+// error object as its single argument whenever an error occurs. Example:
+//
+// // Open the socket
+// let socket = controlSocket("127.0.0.1", 9151, "MyPassw0rd",
+// function (error) { console.log(error.message || error); });
+// // Send command and receive "250" reply or error message
+// socket.sendCommand(commandText, replyCallback);
+// // Register or deregister for "650" notifications
+// // that match regex
+// socket.addNotificationCallback(regex, callback);
+// socket.removeNotificationCallback(callback);
+// // Close the socket permanently
+// socket.close();
+io.controlSocket = function (host, port, password, onError) {
+ // Produce a callback dispatcher for Tor messages.
+ let [onMessage, mainDispatcher] = io.callbackDispatcher(),
+ // Open the socket and convert format to Tor messages.
+ socket = io.asyncSocket(host, port,
+ io.onDataFromOnLine(io.onLineFromOnMessage(onMessage)),
+ onError),
+ // Tor expects any commands to be terminated by CRLF.
+ writeLine = function (text) { socket.write(text + "\r\n"); },
+ // Ensure we return the correct reply for each sendCommand.
+ [sendCommand, onReply, onFailure] = io.matchRepliesToCommands(writeLine),
+ // Create a secondary callback dispatcher for Tor notification messages.
+ [onNotification, notificationDispatcher] = io.callbackDispatcher();
+ // Pass successful reply back to sendCommand callback.
+ mainDispatcher.addCallback(/^2\d\d/, onReply);
+ // Pass error message to sendCommand callback.
+ mainDispatcher.addCallback(/^[45]\d\d/, function (message) {
+ onFailure();
+ onError(new Error(message));
+ });
+ // Pass asynchronous notifications to notification dispatcher.
+ mainDispatcher.addCallback(/^650/, onNotification);
+ // Log in to control port.
+ sendCommand("authenticate " + (password || ""));
+ // Activate needed events.
+ sendCommand("setevents stream circ");
+ return { close : socket.close, sendCommand : sendCommand,
+ addNotificationCallback : notificationDispatcher.addCallback,
+ removeNotificationCallback : notificationDispatcher.removeCallback };
+};
+
+// ## utils
+// A namespace for utility functions
+let utils = utils || {};
+
+// __utils.identity(x)__.
+// Returns its argument unchanged.
+utils.identity = function (x) { return x; };
+
+// __utils.isString(x)__.
+// Returns true iff x is a string.
+utils.isString = function (x) {
+ return typeof(x) === 'string' || x instanceof String;
+};
+
+// __utils.capture(string, regex)__.
+// Takes a string and returns an array of capture items, where regex must have a single
+// capturing group and use the suffix /.../g to specify a global search.
+utils.capture = function (string, regex) {
+ let matches = [];
+ // Special trick to use string.replace for capturing multiple matches.
+ string.replace(regex, function (a, captured) {
+ matches.push(captured);
+ });
+ return matches;
+};
+
+// __utils.extractor(regex)__.
+// Returns a function that takes a string and returns an array of regex matches. The
+// regex must use the suffix /.../g to specify a global search.
+utils.extractor = function (regex) {
+ return function (text) {
+ return utils.capture(text, regex);
+ };
+};
+
+// __utils.splitLines(string)__.
+// Splits a string into an array of strings, each corresponding to a line.
+utils.splitLines = function (string) { return string.split(/\r?\n/); };
+
+// __utils.splitAtSpaces(string)__.
+// Splits a string into chunks between spaces. Does not split at spaces
+// inside pairs of quotation marks.
+utils.splitAtSpaces = utils.extractor(/((\S*?"(.*?)")+\S*|\S+)/g);
+
+// __utils.splitAtEquals(string)__.
+// Splits a string into chunks between equals. Does not split at equals
+// inside pairs of quotation marks.
+utils.splitAtEquals = utils.extractor(/(([^=]*?"(.*?)")+[^=]*|[^=]+)/g);
+
+// __utils.mergeObjects(arrayOfObjects)__.
+// Takes an array of objects like [{"a":"b"},{"c":"d"}] and merges to a single object.
+// Pure function.
+utils.mergeObjects = function (arrayOfObjects) {
+ let result = {};
+ for (let obj of arrayOfObjects) {
+ for (var key in obj) {
+ result[key] = obj[key];
+ }
+ }
+ return result;
+};
+
+// __utils.listMapData(parameterString, listNames)__.
+// Takes a list of parameters separated by spaces, of which the first several are
+// unnamed, and the remainder are named, in the form `NAME=VALUE`. Apply listNames
+// to the unnamed parameters, and combine them in a map with the named parameters.
+// Example: `40 FAILED 0 95.78.59.36:80 REASON=CANT_ATTACH`
+//
+// utils.listMapData("40 FAILED 0 95.78.59.36:80 REASON=CANT_ATTACH",
+// ["streamID", "event", "circuitID", "IP"])
+// // --> {"streamID" : "40", "event" : "FAILED", "circuitID" : "0",
+// // "address" : "95.78.59.36:80", "REASON" : "CANT_ATTACH"}"
+utils.listMapData = function (parameterString, listNames) {
+ // Split out the space-delimited parameters.
+ let parameters = utils.splitAtSpaces(parameterString),
+ dataMap = {};
+ // Assign listNames to the first n = listNames.length parameters.
+ for (let i = 0; i < listNames.length; ++i) {
+ dataMap[listNames[i]] = parameters[i];
+ }
+ // Read key-value pairs and copy these to the dataMap.
+ for (let i = listNames.length; i < parameters.length; ++i) {
+ let [key, value] = utils.splitAtEquals(parameters[i]);
+ if (key && value) {
+ dataMap[key] = value;
+ }
+ }
+ return dataMap;
+};
+
+// ## info
+// A namespace for functions related to tor's GETINFO command.
+let info = info || {};
+
+// __info.keyValueStringsFromMessage(messageText)__.
+// Takes a message (text) response to GETINFO and provides a series of key-value
+// strings, which are either multiline (with a `250+` prefix):
+//
+// 250+config/defaults=
+// AccountingMax "0 bytes"
+// AllowDotExit "0"
+// .
+//
+// or single-line (with a `250-` prefix):
+//
+// 250-version=0.2.6.0-alpha-dev (git-b408125288ad6943)
+info.keyValueStringsFromMessage = utils.extractor(/^(250\+[\s\S]+?^\.|250-.+?)$/gmi);
+
+// __info.applyPerLine(transformFunction)__.
+// Returns a function that splits text into lines,
+// and applies transformFunction to each line.
+info.applyPerLine = function (transformFunction) {
+ return function (text) {
+ return utils.splitLines(text.trim()).map(transformFunction);
+ };
+};
+
+// __info.routerStatusParser(valueString)__.
+// Parses a router status entry as, described in
+// https://gitweb.torproject.org/torspec.git/blob/HEAD:/dir-spec.txt
+// (search for "router status entry")
+info.routerStatusParser = function (valueString) {
+ let lines = utils.splitLines(valueString),
+ objects = [];
+ for (let line of lines) {
+ // Drop first character and grab data following it.
+ let myData = line.substring(2),
+ // Accumulate more maps with data, depending on the first character in the line.
+ dataFun = {
+ "r" : data => utils.listMapData(data, ["nickname", "identity", "digest",
+ "publicationDate", "publicationTime",
+ "IP", "ORPort", "DirPort"]) ,
+ "a" : data => ({ "IPv6" : data }) ,
+ "s" : data => ({ "statusFlags" : utils.splitAtSpaces(data) }) ,
+ "v" : data => ({ "version" : data }) ,
+ "w" : data => utils.listMapData(data, []) ,
+ "p" : data => ({ "portList" : data.split(",") }) ,
+ "m" : data => utils.listMapData(data, [])
+ }[line.charAt(0)];
+ if (dataFun !== undefined) {
+ objects.push(dataFun(myData));
+ }
+ }
+ return utils.mergeObjects(objects);
+};
+
+// __info.circuitStatusParser(line)__.
+// Parse the output of a circuit status line.
+info.circuitStatusParser = function (line) {
+ let data = utils.listMapData(line, ["id","status","circuit"]),
+ circuit = data.circuit;
+ // Parse out the individual circuit IDs and names.
+ if (circuit) {
+ data.circuit = circuit.split(",").map(function (x) {
+ return x.split(/~|=/);
+ });
+ }
+ return data;
+};
+
+// __info.streamStatusParser(line)__.
+// Parse the output of a stream status line.
+info.streamStatusParser = function (text) {
+ return utils.listMapData(text, ["StreamID", "StreamStatus",
+ "CircuitID", "Target"]);
+};
+
+// __info.parsers__.
+// A map of GETINFO keys to parsing function, which convert result strings to JavaScript
+// data.
+info.parsers = {
+ "version" : utils.identity,
+ "config-file" : utils.identity,
+ "config-defaults-file" : utils.identity,
+ "config-text" : utils.identity,
+ "ns/id/" : info.routerStatusParser,
+ "ns/name/" : info.routerStatusParser,
+ "ip-to-country/" : utils.identity,
+ "circuit-status" : info.applyPerLine(info.circuitStatusParser),
+ "stream-status" : info.applyPerLine(info.streamStatusParser)
+};
+
+// __info.getParser(key)__.
+// Takes a key and determines the parser function that should be used to
+// convert its corresponding valueString to JavaScript data.
+info.getParser = function(key) {
+ return info.parsers[key] ||
+ info.parsers[key.substring(0, key.lastIndexOf("/") + 1)] ||
+ "unknown";
+};
+
+// __info.stringToValue(string)__.
+// Converts a key-value string as from GETINFO to a value.
+info.stringToValue = function (string) {
+ // key should look something like `250+circuit-status=` or `250-circuit-status=...`
+ let key = string.match(/^250[\+-](.+?)=/mi)[1],
+ // matchResult finds a single-line result for `250-` or a multi-line one for `250+`.
+ matchResult = string.match(/250\-.+?=(.*?)$/mi) ||
+ string.match(/250\+.+?=([\s\S]*?)^\.$/mi),
+ // Retrieve the captured group (the text of the value in the key-value pair)
+ valueString = matchResult ? matchResult[1] : null;
+ // Return value where the latter has been parsed according to the key requested.
+ return info.getParser(key)(valueString);
+};
+
+// __info.getInfoMultiple(aControlSocket, keys, onData)__.
+// Sends GETINFO for an array of keys. Passes onData an array of their respective results,
+// in order.
+info.getInfoMultiple = function (aControlSocket, keys, onData) {
+ /*
+ if (!(keys instanceof Array)) {
+ throw new Error("keys argument should be an array");
+ }
+ if (!(onData instanceof Function)) {
+ throw new Error("onData argument should be a function");
+ }
+ let parsers = keys.map(info.getParser);
+ if (parsers.indexOf("unknown") !== -1) {
+ throw new Error("unknown key");
+ }
+ if (parsers.indexOf("not supported") !== -1) {
+ throw new Error("unsupported key");
+ }
+ */
+ aControlSocket.sendCommand("getinfo " + keys.join(" "), function (message) {
+ onData(info.keyValueStringsFromMessage(message).map(info.stringToValue));
+ });
+};
+
+// __info.getInfo(controlSocket, key, onValue)__.
+// Sends GETINFO for a single key. Passes onValue the value for that key.
+info.getInfo = function (aControlSocket, key, onValue) {
+ /*
+ if (!utils.isString(key)) {
+ throw new Error("key argument should be a string");
+ }
+ if (!(onValue instanceof Function)) {
+ throw new Error("onValue argument should be a function");
+ }
+ */
+ info.getInfoMultiple(aControlSocket, [key], function (data) {
+ onValue(data[0]);
+ });
+};
+
+// ## event
+// Handlers for events
+
+let event = event || {};
+
+// __event.parsers__.
+// A map of EVENT keys to parsing functions, which convert result strings to JavaScript
+// data.
+event.parsers = {
+ "stream" : info.streamStatusParser,
+ "circ" : info.circuitStatusParser
+};
+
+// __event.messageToData(type, message)__.
+// Extract the data from an event.
+event.messageToData = function (type, message) {
+ let dataText = message.match(/^650 \S+?\s(.*?)$/mi)[1];
+ return dataText ? event.parsers[type.toLowerCase()](dataText) : null;
+};
+
+// __event.watchEvent(controlSocket, type, filter, onData)__.
+// Watches for a particular type of event. If filter(data) returns true, the event's
+// data is pass to the onData callback.
+event.watchEvent = function (controlSocket, type, filter, onData) {
+ controlSocket.addNotificationCallback(new RegExp("^650." + type, "i"),
+ function (message) {
+ let data = event.messageToData(type, message);
+ if (filter === null || filter(data)) {
+ onData(data);
+ }
+ });
+};
+
+// ## tor
+// Things related to the main controller.
+let tor = tor || {};
+
+// __tor.controller(host, port, password, onError)__.
+// Creates a tor controller at the given host and port, with the given password.
+// onError returns asynchronously whenever a connection error occurs.
+tor.controller = function (host, port, password, onError) {
+ let socket = io.controlSocket(host, port, password, onError);
+ return { getInfo : function (key, log) { info.getInfo(socket, key, log); } ,
+ getInfoMultiple : function (keys, log) {
+ info.getInfoMultiple(socket, keys, log);
+ },
+ watchEvent : function (type, filter, onData) {
+ event.watchEvent(socket, type, filter, onData);
+ },
+ close : socket.close };
+};
+
+// __tor.controllerCache__.
+// A map from "host:port" to controller objects. Prevents redundant instantiation
+// of control sockets.
+tor.controllerCache = {};
+
+// ## Export
+
+// __controller(host, port, password, onError)__.
+// Instantiates and returns a controller object connected to a tor ControlPort
+// at host:port, authenticating with the given password, if the controller doesn't yet
+// exist. Otherwise returns the existing controller to the given host:port.
+// onError is called with an error object as its single argument whenever
+// an error occurs. Example:
+//
+// // Get the controller
+// let c = controller("127.0.0.1", 9151, "MyPassw0rd",
+// function (error) { console.log(error.message || error); });
+// // Send command and receive `250` reply or error message
+// c.getInfo("ip-to-country/16.16.16.16", console.log);
+// // Close the controller permanently
+// c.close();
+let controller = function (host, port, password, onError) {
+ let dest = host + ":" + port;
+ return (tor.controllerCache[dest] = tor.controllerCache[dest] ||
+ tor.controller(host, port, password, onError));
+};
+
+// Export the controller function for external use.
+var EXPORTED_SYMBOLS = ["controller"];
1
0
[torbutton/master] Bug #3455.3: Add DomainIsolator, for isolating circuit by domain.
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit 59445b7baed58e712bd38c02e6dc75882ff0c997
Author: Arthur Edelstein <arthuredelstein(a)gmail.com>
Date: Mon Jul 14 00:40:13 2014 -0700
Bug #3455.3: Add DomainIsolator, for isolating circuit by domain.
An XPCOM component that registers a ProtocolProxyChannelFilter
which sets the username/password for each web request according to
url bar domain.
---
src/chrome.manifest | 5 +-
src/components/domain-isolator.js | 128 +++++++++++++++++++++++++++++++++++++
2 files changed, 132 insertions(+), 1 deletion(-)
diff --git a/src/chrome.manifest b/src/chrome.manifest
index af44862..d211984 100644
--- a/src/chrome.manifest
+++ b/src/chrome.manifest
@@ -155,7 +155,10 @@ contract @torproject.org/torbutton-torCheckService;1 {5d57312b-5d8c-4169-b4af-e8
component {f36d72c9-9718-4134-b550-e109638331d7} components/torbutton-logger.js
contract @torproject.org/torbutton-logger;1 {f36d72c9-9718-4134-b550-e109638331d7}
+component {e33fd6d4-270f-475f-a96f-ff3140279f68} components/domain-isolator.js
+contract @torproject.org/domain-isolator;1 {e33fd6d4-270f-475f-a96f-ff3140279f68}
+
category profile-after-change CookieJarSelector @torproject.org/cookie-jar-selector;1
-# category profile-after-change RefSpoofer @torproject.org/torRefSpoofer;1
category profile-after-change TBSessionBlocker @torproject.org/torbutton-ss-blocker;1
category profile-after-change StartupObserver @torproject.org/startup-observer;1
+category profile-after-change DomainIsolator @torproject.org/domain-isolator;1
\ No newline at end of file
diff --git a/src/components/domain-isolator.js b/src/components/domain-isolator.js
new file mode 100644
index 0000000..e8e6bfa
--- /dev/null
+++ b/src/components/domain-isolator.js
@@ -0,0 +1,128 @@
+// # domain-isolator.js
+// A component for TorBrowser that puts requests from different
+// first party domains on separate tor circuits.
+
+// This file is written in call stack order (later functions
+// call earlier functions). The code file can be processed
+// with docco.js to provide clear documentation.
+
+/* jshint moz: true */
+/* global Components, console, XPCOMUtils */
+
+// ### Abbreviations
+const Cc = Components.classes, Ci = Components.interfaces, Cu = Components.utils;
+
+// Make the logger available.
+let logger = Cc["@torproject.org/torbutton-logger;1"]
+ .getService(Components.interfaces.nsISupports).wrappedJSObject;
+
+// ## mozilla namespace.
+// Useful functionality for interacting with Mozilla services.
+let mozilla = mozilla || {};
+
+// __mozilla.protocolProxyService__.
+// Mozilla's protocol proxy service, useful for managing proxy connections made
+// by the browser.
+mozilla.protocolProxyService = Cc["@mozilla.org/network/protocol-proxy-service;1"]
+ .getService(Ci.nsIProtocolProxyService);
+
+// __mozilla.thirdPartyUtil__.
+// Mozilla's Thirdy Party Utilities, for figuring out first party domain.
+mozilla.thirdPartyUtil = Cc["@mozilla.org/thirdpartyutil;1"]
+ .getService(Ci.mozIThirdPartyUtil);
+
+// __mozilla.registerProxyChannelFilter(filterFunction, positionIndex)__.
+// Registers a proxy channel filter with the Mozilla Protocol Proxy Service,
+// which will help to decide the proxy to be used for a given channel.
+// The filterFunction should expect two arguments, (aChannel, aProxy),
+// where aProxy is the proxy or list of proxies that would be used by default
+// for the given channel, and should return a new Proxy or list of Proxies.
+mozilla.registerProxyChannelFilter = function (filterFunction, positionIndex) {
+ let proxyFilter = {
+ applyFilter : function (aProxyService, aChannel, aProxy) {
+ return filterFunction(aChannel, aProxy);
+ }
+ };
+ mozilla.protocolProxyService.registerChannelFilter(proxyFilter, positionIndex);
+};
+
+// ## tor functionality.
+let tor = tor || {};
+
+// __tor.noncesForDomains__.
+// A mutable map that records what nonce we are using for each domain.
+tor.noncesForDomains = {};
+
+// __tor.socksProxyCredentials(originalProxy, domain)__.
+// Takes a proxyInfo object (originalProxy) and returns a new proxyInfo
+// object with the same properties, except the username is set to the
+// the domain, and the password is a nonce.
+tor.socksProxyCredentials = function (originalProxy, domain) {
+ // Check if we already have a nonce. If not, create
+ // one for this domain.
+ if (!tor.noncesForDomains.hasOwnProperty(domain)) {
+ tor.noncesForDomains[domain] = 0;
+ }
+ let proxy = originalProxy.QueryInterface(Ci.nsIProxyInfo);
+ return mozilla.protocolProxyService
+ .newSOCKSProxyInfo(proxy.host,
+ proxy.port,
+ domain, // username
+ tor.noncesForDomains[domain].toString(), // password
+ proxy.flags,
+ proxy.failoverTimeout,
+ proxy.failoverProxy);
+};
+
+// __tor.isolateCircuitsByDomain()__.
+// For every HTTPChannel, replaces the default SOCKS proxy with one that authenticates
+// to the SOCKS server (the tor client process) with a username (the first party domain)
+// and a nonce password. Tor provides a separate circuit for each username+password
+// combination.
+tor.isolateCircuitsByDomain = function () {
+ mozilla.registerProxyChannelFilter(function (aChannel, aProxy) {
+ try {
+ let channel = aChannel.QueryInterface(Ci.nsIHttpChannel),
+ firstPartyURI = mozilla.thirdPartyUtil.getFirstPartyURIFromChannel(channel, true)
+ .QueryInterface(Ci.nsIURI),
+ firstPartyDomain = mozilla.thirdPartyUtil
+ .getFirstPartyHostForIsolation(firstPartyURI),
+ proxy = aProxy.QueryInterface(Ci.nsIProxyInfo),
+ replacementProxy = tor.socksProxyCredentials(aProxy, firstPartyDomain);
+ logger.eclog(3, "tor SOCKS: " + channel.URI.spec + " via " +
+ replacementProxy.username + ":" + replacementProxy.password);
+ return replacementProxy;
+ } catch (err) {
+ // If we fail, then just use the default proxyInfo.
+ return aProxy;
+ }
+ }, 0);
+};
+
+// ## XPCOM component construction.
+// Module specific constants
+const kMODULE_NAME = "TorBrowser Domain Isolator";
+const kMODULE_CONTRACTID = "@torproject.org/domain-isolator;1";
+const kMODULE_CID = Components.ID("e33fd6d4-270f-475f-a96f-ff3140279f68");
+
+// Import XPCOMUtils object.
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+// DomainIsolator object. Constructor does nothing.
+function DomainIsolator() { }
+// Firefox component requirements
+DomainIsolator.prototype = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
+ classDescription: kMODULE_NAME,
+ classID: kMODULE_CID,
+ contractID: kMODULE_CONTRACTID,
+ observe: function (subject, topic, data) {
+ if (topic === "profile-after-change") {
+ logger.eclog(3, "domain isolator: set up isolating circuits by domain");
+ tor.isolateCircuitsByDomain();
+ }
+ }
+};
+
+// Assign factory to global object.
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([DomainIsolator]);
1
0
[tor-browser/tor-browser-31.2.0esr-4.5-1] Bug #3455.2. Allow RFC1929 authentication (username/password) to SOCKS servers.
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit e0eaf6b471ae3bbc06066232a00f3b27c2bedeee
Author: Arthur Edelstein <arthuredelstein(a)gmail.com>
Date: Tue Oct 21 02:17:55 2014 -0700
Bug #3455.2. Allow RFC1929 authentication (username/password) to SOCKS servers.
---
netwerk/base/public/nsIProtocolProxyService.idl | 29 ++++
netwerk/base/public/nsIProxyInfo.idl | 12 +-
netwerk/base/src/nsProtocolProxyService.cpp | 39 ++++-
netwerk/base/src/nsProtocolProxyService.h | 8 +
netwerk/base/src/nsProxyInfo.cpp | 14 ++
netwerk/base/src/nsProxyInfo.h | 2 +
netwerk/base/src/nsSocketTransport2.cpp | 84 +++++++---
netwerk/base/src/nsSocketTransport2.h | 15 +-
netwerk/socket/nsISocketProvider.idl | 9 +-
netwerk/socket/nsSOCKSIOLayer.cpp | 196 +++++++++++++++++-----
netwerk/socket/nsSOCKSIOLayer.h | 4 +-
netwerk/socket/nsSOCKSSocketProvider.cpp | 12 +-
netwerk/socket/nsUDPSocketProvider.cpp | 6 +-
security/manager/ssl/src/nsNSSIOLayer.cpp | 23 ++-
security/manager/ssl/src/nsNSSIOLayer.h | 7 +-
security/manager/ssl/src/nsSSLSocketProvider.cpp | 12 +-
security/manager/ssl/src/nsTLSSocketProvider.cpp | 12 +-
17 files changed, 361 insertions(+), 123 deletions(-)
diff --git a/netwerk/base/public/nsIProtocolProxyService.idl b/netwerk/base/public/nsIProtocolProxyService.idl
index 9365658..f974f40 100644
--- a/netwerk/base/public/nsIProtocolProxyService.idl
+++ b/netwerk/base/public/nsIProtocolProxyService.idl
@@ -136,6 +136,35 @@ interface nsIProtocolProxyService : nsISupports
in nsIProxyInfo aFailoverProxy);
/**
+ * This method may be called to construct a nsIProxyInfo instance for
+ * a SOCKS connection, with the specified username and password.
+ * @param aHost
+ * The proxy hostname or IP address.
+ * @param aPort
+ * The proxy port.
+ * @param aUsername
+ * The SOCKS5 username
+ * @param aPassword
+ * The SOCKS5 password
+ * @param aFlags
+ * Flags associated with this connection. See nsIProxyInfo.idl
+ * for currently defined flags.
+ * @param aFailoverTimeout
+ * Specifies the length of time (in seconds) to ignore this proxy if
+ * this proxy fails. Pass UINT32_MAX to specify the default
+ * timeout value, causing nsIProxyInfo::failoverTimeout to be
+ * assigned the default value.
+ * @param aFailoverProxy
+ * Specifies the next proxy to try if this proxy fails. This
+ * parameter may be null.
+ */
+ nsIProxyInfo newSOCKSProxyInfo(in AUTF8String aHost, in long aPort,
+ in ACString aUsername, in ACString aPassword,
+ in unsigned long aFlags,
+ in unsigned long aFailoverTimeout,
+ in nsIProxyInfo aFailoverProxy);
+
+ /**
* If the proxy identified by aProxyInfo is unavailable for some reason,
* this method may be called to access an alternate proxy that may be used
* instead. As a side-effect, this method may affect future result values
diff --git a/netwerk/base/public/nsIProxyInfo.idl b/netwerk/base/public/nsIProxyInfo.idl
index f6f0bf3..56beb02 100644
--- a/netwerk/base/public/nsIProxyInfo.idl
+++ b/netwerk/base/public/nsIProxyInfo.idl
@@ -8,7 +8,7 @@
/**
* This interface identifies a proxy server.
*/
-[scriptable, uuid(9e557d99-7af0-4895-95b7-e6dba28c9ad9)]
+[scriptable, uuid(63fff172-2564-4138-96c6-3ae7d245fbed)]
interface nsIProxyInfo : nsISupports
{
/**
@@ -50,6 +50,16 @@ interface nsIProxyInfo : nsISupports
readonly attribute unsigned long resolveFlags;
/**
+ * Specifies a SOCKS5 username.
+ */
+ readonly attribute ACString username;
+
+ /**
+ * Specifies a SOCKS5 password.
+ */
+ readonly attribute ACString password;
+
+ /**
* This attribute specifies the failover timeout in seconds for this proxy.
* If a nsIProxyInfo is reported as failed via nsIProtocolProxyService::
* getFailoverForProxy, then the failed proxy will not be used again for this
diff --git a/netwerk/base/src/nsProtocolProxyService.cpp b/netwerk/base/src/nsProtocolProxyService.cpp
index 3878c58d..ed8b311 100644
--- a/netwerk/base/src/nsProtocolProxyService.cpp
+++ b/netwerk/base/src/nsProtocolProxyService.cpp
@@ -516,6 +516,12 @@ nsProtocolProxyService::PrefsChanged(nsIPrefBranch *prefBranch,
if (!pref || !strcmp(pref, PROXY_PREF("socks_port")))
proxy_GetIntPref(prefBranch, PROXY_PREF("socks_port"), mSOCKSProxyPort);
+ if (!pref || !strcmp(pref, PROXY_PREF("socks_username")))
+ proxy_GetStringPref(prefBranch, PROXY_PREF("socks_username"), mSOCKSProxyUsername);
+
+ if (!pref || !strcmp(pref, PROXY_PREF("socks_password")))
+ proxy_GetStringPref(prefBranch, PROXY_PREF("socks_password"), mSOCKSProxyPassword);
+
if (!pref || !strcmp(pref, PROXY_PREF("socks_version"))) {
int32_t version;
proxy_GetIntPref(prefBranch, PROXY_PREF("socks_version"), version);
@@ -1188,10 +1194,25 @@ nsProtocolProxyService::NewProxyInfo(const nsACString &aType,
}
NS_ENSURE_TRUE(type, NS_ERROR_INVALID_ARG);
- if (aPort <= 0)
- aPort = -1;
+ return NewProxyInfo_Internal(type, aHost, aPort,
+ mSOCKSProxyUsername, mSOCKSProxyPassword,
+ aFlags, aFailoverTimeout,
+ aFailoverProxy, 0, aResult);
+}
- return NewProxyInfo_Internal(type, aHost, aPort, aFlags, aFailoverTimeout,
+NS_IMETHODIMP
+nsProtocolProxyService::NewSOCKSProxyInfo(const nsACString &aHost,
+ int32_t aPort,
+ const nsACString &aUsername,
+ const nsACString &aPassword,
+ uint32_t aFlags,
+ uint32_t aFailoverTimeout,
+ nsIProxyInfo *aFailoverProxy,
+ nsIProxyInfo **aResult)
+{
+ return NewProxyInfo_Internal(kProxyType_SOCKS, aHost, aPort,
+ aUsername, aPassword,
+ aFlags, aFailoverTimeout,
aFailoverProxy, 0, aResult);
}
@@ -1496,12 +1517,17 @@ nsresult
nsProtocolProxyService::NewProxyInfo_Internal(const char *aType,
const nsACString &aHost,
int32_t aPort,
+ const nsACString &aUsername,
+ const nsACString &aPassword,
uint32_t aFlags,
uint32_t aFailoverTimeout,
nsIProxyInfo *aFailoverProxy,
uint32_t aResolveFlags,
nsIProxyInfo **aResult)
{
+ if (aPort <= 0)
+ aPort = -1;
+
nsCOMPtr<nsProxyInfo> failover;
if (aFailoverProxy) {
failover = do_QueryInterface(aFailoverProxy);
@@ -1515,6 +1541,8 @@ nsProtocolProxyService::NewProxyInfo_Internal(const char *aType,
proxyInfo->mType = aType;
proxyInfo->mHost = aHost;
proxyInfo->mPort = aPort;
+ proxyInfo->mUsername = aUsername;
+ proxyInfo->mPassword = aPassword;
proxyInfo->mFlags = aFlags;
proxyInfo->mResolveFlags = aResolveFlags;
proxyInfo->mTimeout = aFailoverTimeout == UINT32_MAX
@@ -1680,8 +1708,9 @@ nsProtocolProxyService::Resolve_Internal(nsIChannel *channel,
}
if (type) {
- rv = NewProxyInfo_Internal(type, *host, port, proxyFlags,
- UINT32_MAX, nullptr, flags,
+ rv = NewProxyInfo_Internal(type, *host, port,
+ mSOCKSProxyUsername, mSOCKSProxyPassword,
+ proxyFlags, UINT32_MAX, nullptr, flags,
result);
if (NS_FAILED(rv))
return rv;
diff --git a/netwerk/base/src/nsProtocolProxyService.h b/netwerk/base/src/nsProtocolProxyService.h
index 9ef68b9..04c642f 100644
--- a/netwerk/base/src/nsProtocolProxyService.h
+++ b/netwerk/base/src/nsProtocolProxyService.h
@@ -177,6 +177,10 @@ protected:
* The proxy host name (UTF-8 ok).
* @param port
* The proxy port number.
+ * @param username
+ * The username for the proxy (ASCII). May be "", but not null.
+ * @param password
+ * The password for the proxy (ASCII). May be "", but not null.
* @param flags
* The proxy flags (nsIProxyInfo::flags).
* @param timeout
@@ -191,6 +195,8 @@ protected:
NS_HIDDEN_(nsresult) NewProxyInfo_Internal(const char *type,
const nsACString &host,
int32_t port,
+ const nsACString &username,
+ const nsACString &password,
uint32_t flags,
uint32_t timeout,
nsIProxyInfo *next,
@@ -374,6 +380,8 @@ protected:
int32_t mSOCKSProxyPort;
int32_t mSOCKSProxyVersion;
bool mSOCKSProxyRemoteDNS;
+ nsCString mSOCKSProxyUsername;
+ nsCString mSOCKSProxyPassword;
nsRefPtr<nsPACMan> mPACMan; // non-null if we are using PAC
nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
diff --git a/netwerk/base/src/nsProxyInfo.cpp b/netwerk/base/src/nsProxyInfo.cpp
index 4e727c4..66a78a4 100644
--- a/netwerk/base/src/nsProxyInfo.cpp
+++ b/netwerk/base/src/nsProxyInfo.cpp
@@ -48,6 +48,20 @@ nsProxyInfo::GetResolveFlags(uint32_t *result)
}
NS_IMETHODIMP
+nsProxyInfo::GetUsername(nsACString &result)
+{
+ result = mUsername;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsProxyInfo::GetPassword(nsACString &result)
+{
+ result = mPassword;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
nsProxyInfo::GetFailoverTimeout(uint32_t *result)
{
*result = mTimeout;
diff --git a/netwerk/base/src/nsProxyInfo.h b/netwerk/base/src/nsProxyInfo.h
index 550bbf2..5432d95 100644
--- a/netwerk/base/src/nsProxyInfo.h
+++ b/netwerk/base/src/nsProxyInfo.h
@@ -59,6 +59,8 @@ private:
const char *mType; // pointer to statically allocated value
nsCString mHost;
+ nsCString mUsername;
+ nsCString mPassword;
int32_t mPort;
uint32_t mFlags;
uint32_t mResolveFlags;
diff --git a/netwerk/base/src/nsSocketTransport2.cpp b/netwerk/base/src/nsSocketTransport2.cpp
index e202044..ea0dd68 100644
--- a/netwerk/base/src/nsSocketTransport2.cpp
+++ b/netwerk/base/src/nsSocketTransport2.cpp
@@ -751,7 +751,8 @@ nsSocketTransport::nsSocketTransport()
: mTypes(nullptr)
, mTypeCount(0)
, mPort(0)
- , mProxyPort(0)
+ , mHttpsProxy(false)
+ , mProxyUse(false)
, mProxyTransparent(false)
, mProxyTransparentResolvesHost(false)
, mConnectionFlags(0)
@@ -813,18 +814,25 @@ nsSocketTransport::Init(const char **types, uint32_t typeCount,
const char *proxyType = nullptr;
if (proxyInfo) {
- mProxyPort = proxyInfo->Port();
- mProxyHost = proxyInfo->Host();
+ mProxyInfo = proxyInfo;
// grab proxy type (looking for "socks" for example)
proxyType = proxyInfo->Type();
if (proxyType && (strcmp(proxyType, "http") == 0 ||
strcmp(proxyType, "direct") == 0 ||
strcmp(proxyType, "unknown") == 0))
proxyType = nullptr;
+
+ mProxyUse = true;
+ // check that we don't have a proxyInfo without proxy
+ nsCString proxyHost;
+ proxyInfo->GetHost(proxyHost);
+ if (!proxyType || proxyHost.IsEmpty()) {
+ mProxyUse = false;
+ }
}
- SOCKET_LOG(("nsSocketTransport::Init [this=%p host=%s:%hu proxy=%s:%hu]\n",
- this, mHost.get(), mPort, mProxyHost.get(), mProxyPort));
+ SOCKET_LOG(("nsSocketTransport::Init [this=%x host=%s:%hu proxy=%s]\n",
+ this, mHost.get(), mPort, mProxyUse ? "yes" : "no"));
// include proxy type as a socket type if proxy type is not "http"
mTypeCount = typeCount + (proxyType != nullptr);
@@ -997,7 +1005,7 @@ nsSocketTransport::ResolveHost()
nsresult rv;
- if (!mProxyHost.IsEmpty()) {
+ if (mProxyUse) {
if (!mProxyTransparent || mProxyTransparentResolvesHost) {
#if defined(XP_UNIX)
NS_ABORT_IF_FALSE(!mNetAddrIsSet || mNetAddr.raw.family != AF_LOCAL,
@@ -1079,9 +1087,8 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us
const char *host = mHost.get();
int32_t port = (int32_t) mPort;
- const char *proxyHost = mProxyHost.IsEmpty() ? nullptr : mProxyHost.get();
- int32_t proxyPort = (int32_t) mProxyPort;
uint32_t proxyFlags = 0;
+ nsCOMPtr<nsIProxyInfo> proxy = mProxyInfo;
uint32_t i;
for (i=0; i<mTypeCount; ++i) {
@@ -1102,12 +1109,19 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us
if (mConnectionFlags & nsISocketTransport::NO_PERMANENT_STORAGE)
proxyFlags |= nsISocketProvider::NO_PERMANENT_STORAGE;
+
nsCOMPtr<nsISupports> secinfo;
if (i == 0) {
// if this is the first type, we'll want the
// service to allocate a new socket
+ nsCString proxyHost;
+ GetHost(proxyHost);
+ int32_t proxyPort;
+ GetPort(&proxyPort);
rv = provider->NewSocket(mNetAddr.raw.family,
- host, port, proxyHost, proxyPort,
+ mHttpsProxy ? proxyHost.get() : host,
+ mHttpsProxy ? proxyPort : port,
+ proxy,
proxyFlags, &fd,
getter_AddRefs(secinfo));
@@ -1121,7 +1135,7 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us
// so we just want the service to add itself
// to the stack (such as pushing an io layer)
rv = provider->AddToSocket(mNetAddr.raw.family,
- host, port, proxyHost, proxyPort,
+ host, port, proxy,
proxyFlags, fd,
getter_AddRefs(secinfo));
}
@@ -1151,8 +1165,7 @@ nsSocketTransport::BuildSocket(PRFileDesc *&fd, bool &proxyTransparent, bool &us
(strcmp(mTypes[i], "socks4") == 0)) {
// since socks is transparent, any layers above
// it do not have to worry about proxy stuff
- proxyHost = nullptr;
- proxyPort = -1;
+ proxy = nullptr;
proxyTransparent = true;
}
}
@@ -1211,10 +1224,14 @@ nsSocketTransport::InitiateSocket()
netAddrCString.BeginWriting(),
kIPv6CStrBufSize))
netAddrCString = NS_LITERAL_CSTRING("<IP-to-string failed>");
+ nsCString proxyHost;
+ GetHost(proxyHost);
+ int32_t proxyPort;
+ GetPort(&proxyPort);
SOCKET_LOG(("nsSocketTransport::InitiateSocket skipping "
"speculative connection for host [%s:%d] proxy "
"[%s:%d] with Local IP address [%s]",
- mHost.get(), mPort, mProxyHost.get(), mProxyPort,
+ mHost.get(), mPort, proxyHost.get(), proxyPort,
netAddrCString.get()));
}
#endif
@@ -1363,7 +1380,7 @@ nsSocketTransport::InitiateSocket()
//
OnSocketConnected();
- if (mSecInfo && !mProxyHost.IsEmpty() && proxyTransparent && usingSSL) {
+ if (mSecInfo && mProxyUse && proxyTransparent && usingSSL) {
// if the connection phase is finished, and the ssl layer has
// been pushed, and we were proxying (transparently; ie. nothing
// has to happen in the protocol layer above us), it's time for
@@ -1387,8 +1404,7 @@ nsSocketTransport::InitiateSocket()
// the OS error
//
else if (PR_UNKNOWN_ERROR == code &&
- mProxyTransparent &&
- !mProxyHost.IsEmpty()) {
+ mProxyUse && mProxyTransparent) {
code = PR_GetOSError();
rv = ErrorAccordingToNSPR(code);
}
@@ -1397,7 +1413,7 @@ nsSocketTransport::InitiateSocket()
//
else {
rv = ErrorAccordingToNSPR(code);
- if ((rv == NS_ERROR_CONNECTION_REFUSED) && !mProxyHost.IsEmpty())
+ if (rv == NS_ERROR_CONNECTION_REFUSED && mProxyUse)
rv = NS_ERROR_PROXY_CONNECTION_REFUSED;
}
}
@@ -1709,8 +1725,8 @@ nsSocketTransport::OnSocketEvent(uint32_t type, nsresult status, nsISupports *pa
// For SOCKS proxies (mProxyTransparent == true), the socket
// transport resolves the real host here, so there's no fixup
// (see bug 226943).
- if ((status == NS_ERROR_UNKNOWN_HOST) && !mProxyTransparent &&
- !mProxyHost.IsEmpty())
+ if (status == NS_ERROR_UNKNOWN_HOST && !mProxyTransparent &&
+ mProxyUse)
mCondition = NS_ERROR_UNKNOWN_PROXY_HOST;
else
mCondition = status;
@@ -1835,8 +1851,7 @@ nsSocketTransport::OnSocketReady(PRFileDesc *fd, int16_t outFlags)
// The SOCKS proxy rejected our request. Find out why.
//
else if (PR_UNKNOWN_ERROR == code &&
- mProxyTransparent &&
- !mProxyHost.IsEmpty()) {
+ mProxyUse && mProxyTransparent) {
code = PR_GetOSError();
mCondition = ErrorAccordingToNSPR(code);
}
@@ -1845,7 +1860,7 @@ nsSocketTransport::OnSocketReady(PRFileDesc *fd, int16_t outFlags)
// else, the connection failed...
//
mCondition = ErrorAccordingToNSPR(code);
- if ((mCondition == NS_ERROR_CONNECTION_REFUSED) && !mProxyHost.IsEmpty())
+ if (mCondition == NS_ERROR_CONNECTION_REFUSED && mProxyUse)
mCondition = NS_ERROR_PROXY_CONNECTION_REFUSED;
SOCKET_LOG((" connection failed! [reason=%x]\n", mCondition));
}
@@ -2168,6 +2183,31 @@ nsSocketTransport::GetPort(int32_t *port)
return NS_OK;
}
+const nsCString &
+nsSocketTransport::SocketHost()
+{
+ if (mProxyInfo && !mProxyTransparent) {
+ if (mProxyHostCache.IsEmpty()) {
+ mProxyInfo->GetHost(mProxyHostCache);
+ }
+ return mProxyHostCache;
+ }
+ else
+ return mHost;
+}
+
+uint16_t
+nsSocketTransport::SocketPort()
+{
+ if (mProxyInfo && !mProxyTransparent) {
+ int32_t result;
+ mProxyInfo->GetPort(&result);
+ return (uint16_t) result;
+ }
+ else
+ return mPort;
+}
+
NS_IMETHODIMP
nsSocketTransport::GetPeerAddr(NetAddr *addr)
{
diff --git a/netwerk/base/src/nsSocketTransport2.h b/netwerk/base/src/nsSocketTransport2.h
index 8d822bf..73f750e 100644
--- a/netwerk/base/src/nsSocketTransport2.h
+++ b/netwerk/base/src/nsSocketTransport2.h
@@ -266,15 +266,18 @@ private:
char **mTypes;
uint32_t mTypeCount;
nsCString mHost;
- nsCString mProxyHost;
uint16_t mPort;
- uint16_t mProxyPort;
- bool mProxyTransparent;
- bool mProxyTransparentResolvesHost;
+ bool mHttpsProxy;
+
+ nsCOMPtr<nsIProxyInfo> mProxyInfo;
+ bool mProxyUse;
+ bool mProxyTransparent;
+ bool mProxyTransparentResolvesHost;
uint32_t mConnectionFlags;
- uint16_t SocketPort() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyPort : mPort; }
- const nsCString &SocketHost() { return (!mProxyHost.IsEmpty() && !mProxyTransparent) ? mProxyHost : mHost; }
+ uint16_t SocketPort();
+ const nsCString &SocketHost();
+ nsCString mProxyHostCache; // for SocketHost() only
//-------------------------------------------------------------------------
// members accessible only on the socket transport thread:
diff --git a/netwerk/socket/nsISocketProvider.idl b/netwerk/socket/nsISocketProvider.idl
index 57f6c4d..0dd316c 100644
--- a/netwerk/socket/nsISocketProvider.idl
+++ b/netwerk/socket/nsISocketProvider.idl
@@ -5,12 +5,13 @@
#include "nsISupports.idl"
+interface nsIProxyInfo;
[ptr] native PRFileDescStar(struct PRFileDesc);
/**
* nsISocketProvider
*/
-[scriptable, uuid(00b3df92-e830-11d8-d48e-0004e22243f8)]
+[scriptable, uuid(508d5469-9e1e-4a08-b5b0-7cfebba1e51a)]
interface nsISocketProvider : nsISupports
{
/**
@@ -38,8 +39,7 @@ interface nsISocketProvider : nsISupports
void newSocket(in long aFamily,
in string aHost,
in long aPort,
- in string aProxyHost,
- in long aProxyPort,
+ in nsIProxyInfo aProxy,
in unsigned long aFlags,
out PRFileDescStar aFileDesc,
out nsISupports aSecurityInfo);
@@ -58,8 +58,7 @@ interface nsISocketProvider : nsISupports
void addToSocket(in long aFamily,
in string aHost,
in long aPort,
- in string aProxyHost,
- in long aProxyPort,
+ in nsIProxyInfo aProxy,
in unsigned long aFlags,
in PRFileDescStar aFileDesc,
out nsISupports aSecurityInfo);
diff --git a/netwerk/socket/nsSOCKSIOLayer.cpp b/netwerk/socket/nsSOCKSIOLayer.cpp
index e03b94c..f3250b9 100644
--- a/netwerk/socket/nsSOCKSIOLayer.cpp
+++ b/netwerk/socket/nsSOCKSIOLayer.cpp
@@ -50,6 +50,8 @@ class nsSOCKSSocketInfo : public nsISOCKSSocketInfo
SOCKS4_READ_CONNECT_RESPONSE,
SOCKS5_WRITE_AUTH_REQUEST,
SOCKS5_READ_AUTH_RESPONSE,
+ SOCKS5_WRITE_USERNAME_REQUEST,
+ SOCKS5_READ_USERNAME_RESPONSE,
SOCKS5_WRITE_CONNECT_REQUEST,
SOCKS5_READ_CONNECT_RESPONSE_TOP,
SOCKS5_READ_CONNECT_RESPONSE_BOTTOM,
@@ -57,10 +59,12 @@ class nsSOCKSSocketInfo : public nsISOCKSSocketInfo
SOCKS_FAILED
};
- // A buffer of 262 bytes should be enough for any request and response
+ // A buffer of 520 bytes should be enough for any request and response
// in case of SOCKS4 as well as SOCKS5
- static const uint32_t BUFFER_SIZE = 262;
+ static const uint32_t BUFFER_SIZE = 520;
static const uint32_t MAX_HOSTNAME_LEN = 255;
+ static const uint32_t MAX_USERNAME_LEN = 255;
+ static const uint32_t MAX_PASSWORD_LEN = 255;
public:
nsSOCKSSocketInfo();
@@ -72,8 +76,7 @@ public:
void Init(int32_t version,
int32_t family,
- const char *proxyHost,
- int32_t proxyPort,
+ nsIProxyInfo *proxy,
const char *destinationHost,
uint32_t flags);
@@ -95,6 +98,8 @@ private:
PRStatus ReadV4ConnectResponse();
PRStatus WriteV5AuthRequest();
PRStatus ReadV5AuthResponse();
+ PRStatus WriteV5UsernameRequest();
+ PRStatus ReadV5UsernameResponse();
PRStatus WriteV5ConnectRequest();
PRStatus ReadV5AddrTypeAndLength(uint8_t *type, uint32_t *len);
PRStatus ReadV5ConnectResponseTop();
@@ -130,8 +135,7 @@ private:
PRFileDesc *mFD;
nsCString mDestinationHost;
- nsCString mProxyHost;
- int32_t mProxyPort;
+ nsCOMPtr<nsIProxyInfo> mProxy;
int32_t mVersion; // SOCKS version 4 or 5
int32_t mDestinationFamily;
uint32_t mFlags;
@@ -139,6 +143,7 @@ private:
NetAddr mExternalProxyAddr;
NetAddr mDestinationAddr;
PRIntervalTime mTimeout;
+ nsCString mProxyUsername; // Cache, from mProxy
};
nsSOCKSSocketInfo::nsSOCKSSocketInfo()
@@ -147,7 +152,6 @@ nsSOCKSSocketInfo::nsSOCKSSocketInfo()
, mDataLength(0)
, mReadOffset(0)
, mAmountToRead(0)
- , mProxyPort(-1)
, mVersion(-1)
, mDestinationFamily(AF_INET)
, mFlags(0)
@@ -169,14 +173,14 @@ nsSOCKSSocketInfo::nsSOCKSSocketInfo()
}
void
-nsSOCKSSocketInfo::Init(int32_t version, int32_t family, const char *proxyHost, int32_t proxyPort, const char *host, uint32_t flags)
+nsSOCKSSocketInfo::Init(int32_t version, int32_t family, nsIProxyInfo *proxy, const char *host, uint32_t flags)
{
mVersion = version;
mDestinationFamily = family;
- mProxyHost = proxyHost;
- mProxyPort = proxyPort;
+ mProxy = proxy;
mDestinationHost = host;
mFlags = flags;
+ mProxy->GetUsername(mProxyUsername); // cache
}
NS_IMPL_ISUPPORTS(nsSOCKSSocketInfo, nsISOCKSSocketInfo, nsIDNSListener)
@@ -263,14 +267,17 @@ nsSOCKSSocketInfo::StartDNS(PRFileDesc *fd)
if (!dns)
return PR_FAILURE;
+ nsCString proxyHost;
+ mProxy->GetHost(proxyHost);
+
mFD = fd;
- nsresult rv = dns->AsyncResolve(mProxyHost, 0, this,
+ nsresult rv = dns->AsyncResolve(proxyHost, 0, this,
NS_GetCurrentThread(),
getter_AddRefs(mLookup));
if (NS_FAILED(rv)) {
LOGERROR(("socks: DNS lookup for SOCKS proxy %s failed",
- mProxyHost.get()));
+ proxyHost.get()));
return PR_FAILURE;
}
mState = SOCKS_DNS_IN_PROGRESS;
@@ -315,16 +322,21 @@ nsSOCKSSocketInfo::ConnectToProxy(PRFileDesc *fd)
mVersion = 5;
}
+ int32_t proxyPort;
+ mProxy->GetPort(&proxyPort);
+
int32_t addresses = 0;
do {
if (addresses++)
- mDnsRec->ReportUnusable(mProxyPort);
+ mDnsRec->ReportUnusable(proxyPort);
- rv = mDnsRec->GetNextAddr(mProxyPort, &mInternalProxyAddr);
+ rv = mDnsRec->GetNextAddr(proxyPort, &mInternalProxyAddr);
// No more addresses to try? If so, we'll need to bail
if (NS_FAILED(rv)) {
+ nsCString proxyHost;
+ mProxy->GetHost(proxyHost);
LOGERROR(("socks: unable to connect to SOCKS proxy, %s",
- mProxyHost.get()));
+ proxyHost.get()));
return PR_FAILURE;
}
@@ -440,6 +452,12 @@ nsSOCKSSocketInfo::ContinueConnectingToProxy(PRFileDesc *fd, int16_t oflags)
PRStatus
nsSOCKSSocketInfo::WriteV4ConnectRequest()
{
+ if (mProxyUsername.Length() > MAX_USERNAME_LEN) {
+ LOGERROR(("socks username is too long"));
+ HandshakeFinished(PR_UNKNOWN_ERROR);
+ return PR_FAILURE;
+ }
+
NetAddr *addr = &mDestinationAddr;
int32_t proxy_resolve;
@@ -465,7 +483,9 @@ nsSOCKSSocketInfo::WriteV4ConnectRequest()
// than 0, is used to notify the proxy that this is a SOCKS 4a
// request. This request type works for Tor and perhaps others.
WriteUint32(htonl(0x00000001)); // Fake IP
- WriteUint8(0x00); // Send an emtpy username
+ WriteString(mProxyUsername); // Send username. May be empty.
+ WriteUint8(0x00); // Null-terminate username
+ // Password not supported by V4.
if (mDestinationHost.Length() > MAX_HOSTNAME_LEN) {
LOGERROR(("socks4: destination host name is too long!"));
HandshakeFinished(PR_BAD_ADDRESS_ERROR);
@@ -475,7 +495,9 @@ nsSOCKSSocketInfo::WriteV4ConnectRequest()
WriteUint8(0x00);
} else if (addr->raw.family == AF_INET) {
WriteNetAddr(addr); // Add the IPv4 address
- WriteUint8(0x00); // Send an emtpy username
+ WriteString(mProxyUsername); // Send username. May be empty.
+ WriteUint8(0x00); // Null-terminate username
+ // Password not supported by V4.
} else if (addr->raw.family == AF_INET6) {
LOGERROR(("socks: SOCKS 4 can't handle IPv6 addresses!"));
HandshakeFinished(PR_BAD_ADDRESS_ERROR);
@@ -490,11 +512,15 @@ nsSOCKSSocketInfo::ReadV4ConnectResponse()
{
NS_ABORT_IF_FALSE(mState == SOCKS4_READ_CONNECT_RESPONSE,
"Handling SOCKS 4 connection reply in wrong state!");
- NS_ABORT_IF_FALSE(mDataLength == 8,
- "SOCKS 4 connection reply must be 8 bytes!");
LOGDEBUG(("socks4: checking connection reply"));
+ if (mDataLength != 8) {
+ LOGERROR(("SOCKS 4 connection reply must be 8 bytes!"));
+ HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
+ return PR_FAILURE;
+ }
+
if (ReadUint8() != 0x00) {
LOGERROR(("socks4: wrong connection reply"));
HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
@@ -518,13 +544,18 @@ nsSOCKSSocketInfo::WriteV5AuthRequest()
{
NS_ABORT_IF_FALSE(mVersion == 5, "SOCKS version must be 5!");
+ mDataLength = 0;
mState = SOCKS5_WRITE_AUTH_REQUEST;
// Send an initial SOCKS 5 greeting
LOGDEBUG(("socks5: sending auth methods"));
WriteUint8(0x05); // version -- 5
- WriteUint8(0x01); // # auth methods -- 1
- WriteUint8(0x00); // we don't support authentication
+ WriteUint8(0x01); // # of auth methods -- 1
+ if (mProxyUsername.IsEmpty()) {
+ WriteUint8(0x00); // no authentication
+ } else {
+ WriteUint8(0x02); // username/password
+ }
return PR_SUCCESS;
}
@@ -534,10 +565,12 @@ nsSOCKSSocketInfo::ReadV5AuthResponse()
{
NS_ABORT_IF_FALSE(mState == SOCKS5_READ_AUTH_RESPONSE,
"Handling SOCKS 5 auth method reply in wrong state!");
- NS_ABORT_IF_FALSE(mDataLength == 2,
- "SOCKS 5 auth method reply must be 2 bytes!");
- LOGDEBUG(("socks5: checking auth method reply"));
+ if (mDataLength != 2) {
+ LOGERROR(("SOCKS 5 auth method reply must be 2 bytes"));
+ HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
+ return PR_FAILURE;
+ }
// Check version number
if (ReadUint8() != 0x05) {
@@ -546,12 +579,82 @@ nsSOCKSSocketInfo::ReadV5AuthResponse()
return PR_FAILURE;
}
- // Make sure our authentication choice was accepted
- if (ReadUint8() != 0x00) {
+ // Make sure our authentication choice was accepted,
+ // and continue accordingly
+ uint8_t authMethod = ReadUint8();
+ if (mProxyUsername.IsEmpty() && authMethod == 0x00) { // no auth
+ LOGDEBUG(("socks5: server allows connection without authentication"));
+ return WriteV5ConnectRequest();
+ } else if (!mProxyUsername.IsEmpty() && authMethod == 0x02) { // username/pw
+ LOGDEBUG(("socks5: auth method accepted by server"));
+ return WriteV5UsernameRequest();
+ } else { // 0xFF signals error
LOGERROR(("socks5: server did not accept our authentication method"));
HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
return PR_FAILURE;
}
+}
+
+PRStatus
+nsSOCKSSocketInfo::WriteV5UsernameRequest()
+{
+ NS_ABORT_IF_FALSE(mVersion == 5, "SOCKS version must be 5!");
+
+ if (mProxyUsername.Length() > MAX_USERNAME_LEN) {
+ LOGERROR(("socks username is too long"));
+ HandshakeFinished(PR_UNKNOWN_ERROR);
+ return PR_FAILURE;
+ }
+
+ nsCString password;
+ mProxy->GetPassword(password);
+ if (password.Length() > MAX_PASSWORD_LEN) {
+ LOGERROR(("socks password is too long"));
+ HandshakeFinished(PR_UNKNOWN_ERROR);
+ return PR_FAILURE;
+ }
+
+ mDataLength = 0;
+ mState = SOCKS5_WRITE_USERNAME_REQUEST;
+
+ LOGDEBUG(("socks5: sending username and password"));
+ // RFC 1929 Username/password auth for SOCKS 5
+ WriteUint8(0x01); // version 1 (not 5)
+ WriteUint8(mProxyUsername.Length()); // username length
+ WriteString(mProxyUsername); // username
+ WriteUint8(password.Length()); // password length
+ WriteString(password); // password. WARNING: Sent unencrypted!
+
+ return PR_SUCCESS;
+}
+
+PRStatus
+nsSOCKSSocketInfo::ReadV5UsernameResponse()
+{
+ NS_ABORT_IF_FALSE(mState == SOCKS5_READ_USERNAME_RESPONSE,
+ "Handling SOCKS 5 username/password reply in wrong state!");
+
+ if (mDataLength != 2) {
+ LOGERROR(("SOCKS 5 username reply must be 2 bytes"));
+ HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
+ return PR_FAILURE;
+ }
+
+ // Check version number, must be 1 (not 5)
+ if (ReadUint8() != 0x01) {
+ LOGERROR(("socks5: unexpected version in the reply"));
+ HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
+ return PR_FAILURE;
+ }
+
+ // Check whether username/password were accepted
+ if (ReadUint8() != 0x00) { // 0 = success
+ LOGERROR(("socks5: username/password not accepted"));
+ HandshakeFinished(PR_CONNECT_REFUSED_ERROR);
+ return PR_FAILURE;
+ }
+
+ LOGDEBUG(("socks5: username/password accepted by server"));
return WriteV5ConnectRequest();
}
@@ -795,6 +898,16 @@ nsSOCKSSocketInfo::DoHandshake(PRFileDesc *fd, int16_t oflags)
if (ReadFromSocket(fd) != PR_SUCCESS)
return PR_FAILURE;
return ReadV5AuthResponse();
+ case SOCKS5_WRITE_USERNAME_REQUEST:
+ if (WriteToSocket(fd) != PR_SUCCESS)
+ return PR_FAILURE;
+ WantRead(2);
+ mState = SOCKS5_READ_USERNAME_RESPONSE;
+ return PR_SUCCESS;
+ case SOCKS5_READ_USERNAME_RESPONSE:
+ if (ReadFromSocket(fd) != PR_SUCCESS)
+ return PR_FAILURE;
+ return ReadV5UsernameResponse();
case SOCKS5_WRITE_CONNECT_REQUEST:
if (WriteToSocket(fd) != PR_SUCCESS)
return PR_FAILURE;
@@ -839,10 +952,12 @@ nsSOCKSSocketInfo::GetPollFlags() const
return PR_POLL_EXCEPT | PR_POLL_WRITE;
case SOCKS4_WRITE_CONNECT_REQUEST:
case SOCKS5_WRITE_AUTH_REQUEST:
+ case SOCKS5_WRITE_USERNAME_REQUEST:
case SOCKS5_WRITE_CONNECT_REQUEST:
return PR_POLL_WRITE;
case SOCKS4_READ_CONNECT_RESPONSE:
case SOCKS5_READ_AUTH_RESPONSE:
+ case SOCKS5_READ_USERNAME_RESPONSE:
case SOCKS5_READ_CONNECT_RESPONSE_TOP:
case SOCKS5_READ_CONNECT_RESPONSE_BOTTOM:
return PR_POLL_READ;
@@ -856,7 +971,7 @@ nsSOCKSSocketInfo::GetPollFlags() const
inline void
nsSOCKSSocketInfo::WriteUint8(uint8_t v)
{
- NS_ABORT_IF_FALSE(mDataLength + sizeof(v) <= BUFFER_SIZE,
+ MOZ_RELEASE_ASSERT(mDataLength + sizeof(v) <= BUFFER_SIZE,
"Can't write that much data!");
mData[mDataLength] = v;
mDataLength += sizeof(v);
@@ -865,7 +980,7 @@ nsSOCKSSocketInfo::WriteUint8(uint8_t v)
inline void
nsSOCKSSocketInfo::WriteUint16(uint16_t v)
{
- NS_ABORT_IF_FALSE(mDataLength + sizeof(v) <= BUFFER_SIZE,
+ MOZ_RELEASE_ASSERT(mDataLength + sizeof(v) <= BUFFER_SIZE,
"Can't write that much data!");
memcpy(mData + mDataLength, &v, sizeof(v));
mDataLength += sizeof(v);
@@ -874,7 +989,7 @@ nsSOCKSSocketInfo::WriteUint16(uint16_t v)
inline void
nsSOCKSSocketInfo::WriteUint32(uint32_t v)
{
- NS_ABORT_IF_FALSE(mDataLength + sizeof(v) <= BUFFER_SIZE,
+ MOZ_RELEASE_ASSERT(mDataLength + sizeof(v) <= BUFFER_SIZE,
"Can't write that much data!");
memcpy(mData + mDataLength, &v, sizeof(v));
mDataLength += sizeof(v);
@@ -894,8 +1009,8 @@ nsSOCKSSocketInfo::WriteNetAddr(const NetAddr *addr)
len = sizeof(addr->inet6.ip.u8);
}
- NS_ABORT_IF_FALSE(ip != nullptr, "Unknown address");
- NS_ABORT_IF_FALSE(mDataLength + len <= BUFFER_SIZE,
+ MOZ_RELEASE_ASSERT(ip != nullptr, "Unknown address");
+ MOZ_RELEASE_ASSERT(mDataLength + len <= BUFFER_SIZE,
"Can't write that much data!");
memcpy(mData + mDataLength, ip, len);
@@ -911,7 +1026,7 @@ nsSOCKSSocketInfo::WriteNetPort(const NetAddr *addr)
void
nsSOCKSSocketInfo::WriteString(const nsACString &str)
{
- NS_ABORT_IF_FALSE(mDataLength + str.Length() <= BUFFER_SIZE,
+ MOZ_RELEASE_ASSERT(mDataLength + str.Length() <= BUFFER_SIZE,
"Can't write that much data!");
memcpy(mData + mDataLength, str.Data(), str.Length());
mDataLength += str.Length();
@@ -921,7 +1036,7 @@ inline uint8_t
nsSOCKSSocketInfo::ReadUint8()
{
uint8_t rv;
- NS_ABORT_IF_FALSE(mReadOffset + sizeof(rv) <= mDataLength,
+ MOZ_RELEASE_ASSERT(mReadOffset + sizeof(rv) <= mDataLength,
"Not enough space to pop a uint8_t!");
rv = mData[mReadOffset];
mReadOffset += sizeof(rv);
@@ -932,7 +1047,7 @@ inline uint16_t
nsSOCKSSocketInfo::ReadUint16()
{
uint16_t rv;
- NS_ABORT_IF_FALSE(mReadOffset + sizeof(rv) <= mDataLength,
+ MOZ_RELEASE_ASSERT(mReadOffset + sizeof(rv) <= mDataLength,
"Not enough space to pop a uint16_t!");
memcpy(&rv, mData + mReadOffset, sizeof(rv));
mReadOffset += sizeof(rv);
@@ -943,7 +1058,7 @@ inline uint32_t
nsSOCKSSocketInfo::ReadUint32()
{
uint32_t rv;
- NS_ABORT_IF_FALSE(mReadOffset + sizeof(rv) <= mDataLength,
+ MOZ_RELEASE_ASSERT(mReadOffset + sizeof(rv) <= mDataLength,
"Not enough space to pop a uint32_t!");
memcpy(&rv, mData + mReadOffset, sizeof(rv));
mReadOffset += sizeof(rv);
@@ -959,12 +1074,12 @@ nsSOCKSSocketInfo::ReadNetAddr(NetAddr *addr, uint16_t fam)
addr->raw.family = fam;
if (fam == AF_INET) {
amt = sizeof(addr->inet.ip);
- NS_ABORT_IF_FALSE(mReadOffset + amt <= mDataLength,
+ MOZ_RELEASE_ASSERT(mReadOffset + amt <= mDataLength,
"Not enough space to pop an ipv4 addr!");
memcpy(&addr->inet.ip, ip, amt);
} else if (fam == AF_INET6) {
amt = sizeof(addr->inet6.ip.u8);
- NS_ABORT_IF_FALSE(mReadOffset + amt <= mDataLength,
+ MOZ_RELEASE_ASSERT(mReadOffset + amt <= mDataLength,
"Not enough space to pop an ipv6 addr!");
memcpy(addr->inet6.ip.u8, ip, amt);
}
@@ -983,7 +1098,7 @@ nsSOCKSSocketInfo::WantRead(uint32_t sz)
{
NS_ABORT_IF_FALSE(mDataIoPtr == nullptr,
"WantRead() called while I/O already in progress!");
- NS_ABORT_IF_FALSE(mDataLength + sz <= BUFFER_SIZE,
+ MOZ_RELEASE_ASSERT(mDataLength + sz <= BUFFER_SIZE,
"Can't read that much data!");
mAmountToRead = sz;
}
@@ -1221,8 +1336,7 @@ nsresult
nsSOCKSIOLayerAddToSocket(int32_t family,
const char *host,
int32_t port,
- const char *proxyHost,
- int32_t proxyPort,
+ nsIProxyInfo *proxy,
int32_t socksVersion,
uint32_t flags,
PRFileDesc *fd,
@@ -1289,7 +1403,7 @@ nsSOCKSIOLayerAddToSocket(int32_t family,
}
NS_ADDREF(infoObject);
- infoObject->Init(socksVersion, family, proxyHost, proxyPort, host, flags);
+ infoObject->Init(socksVersion, family, proxy, host, flags);
layer->secret = (PRFilePrivate*) infoObject;
rv = PR_PushIOLayer(fd, PR_GetLayersIdentity(fd), layer);
diff --git a/netwerk/socket/nsSOCKSIOLayer.h b/netwerk/socket/nsSOCKSIOLayer.h
index dfe7c0c..54d936e 100644
--- a/netwerk/socket/nsSOCKSIOLayer.h
+++ b/netwerk/socket/nsSOCKSIOLayer.h
@@ -9,12 +9,12 @@
#include "prio.h"
#include "nscore.h"
+#include "nsIProxyInfo.h"
nsresult nsSOCKSIOLayerAddToSocket(int32_t family,
const char *host,
int32_t port,
- const char *proxyHost,
- int32_t proxyPort,
+ nsIProxyInfo *proxyInfo,
int32_t socksVersion,
uint32_t flags,
PRFileDesc *fd,
diff --git a/netwerk/socket/nsSOCKSSocketProvider.cpp b/netwerk/socket/nsSOCKSSocketProvider.cpp
index af7c9b5..c5a5655 100644
--- a/netwerk/socket/nsSOCKSSocketProvider.cpp
+++ b/netwerk/socket/nsSOCKSSocketProvider.cpp
@@ -44,8 +44,7 @@ NS_IMETHODIMP
nsSOCKSSocketProvider::NewSocket(int32_t family,
const char *host,
int32_t port,
- const char *proxyHost,
- int32_t proxyPort,
+ nsIProxyInfo *proxy,
uint32_t flags,
PRFileDesc **result,
nsISupports **socksInfo)
@@ -59,8 +58,7 @@ nsSOCKSSocketProvider::NewSocket(int32_t family,
nsresult rv = nsSOCKSIOLayerAddToSocket(family,
host,
port,
- proxyHost,
- proxyPort,
+ proxy,
mVersion,
flags,
sock,
@@ -77,8 +75,7 @@ NS_IMETHODIMP
nsSOCKSSocketProvider::AddToSocket(int32_t family,
const char *host,
int32_t port,
- const char *proxyHost,
- int32_t proxyPort,
+ nsIProxyInfo *proxy,
uint32_t flags,
PRFileDesc *sock,
nsISupports **socksInfo)
@@ -86,8 +83,7 @@ nsSOCKSSocketProvider::AddToSocket(int32_t family,
nsresult rv = nsSOCKSIOLayerAddToSocket(family,
host,
port,
- proxyHost,
- proxyPort,
+ proxy,
mVersion,
flags,
sock,
diff --git a/netwerk/socket/nsUDPSocketProvider.cpp b/netwerk/socket/nsUDPSocketProvider.cpp
index 4ca7b29..f03b624 100644
--- a/netwerk/socket/nsUDPSocketProvider.cpp
+++ b/netwerk/socket/nsUDPSocketProvider.cpp
@@ -16,8 +16,7 @@ NS_IMETHODIMP
nsUDPSocketProvider::NewSocket(int32_t aFamily,
const char *aHost,
int32_t aPort,
- const char *aProxyHost,
- int32_t aProxyPort,
+ nsIProxyInfo *aProxy,
uint32_t aFlags,
PRFileDesc * *aFileDesc,
nsISupports **aSecurityInfo)
@@ -36,8 +35,7 @@ NS_IMETHODIMP
nsUDPSocketProvider::AddToSocket(int32_t aFamily,
const char *aHost,
int32_t aPort,
- const char *aProxyHost,
- int32_t aProxyPort,
+ nsIProxyInfo *aProxy,
uint32_t aFlags,
struct PRFileDesc * aFileDesc,
nsISupports **aSecurityInfo)
diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp
index 43bb013..a71f265 100644
--- a/security/manager/ssl/src/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/src/nsNSSIOLayer.cpp
@@ -1598,8 +1598,7 @@ nsresult
nsSSLIOLayerNewSocket(int32_t family,
const char* host,
int32_t port,
- const char* proxyHost,
- int32_t proxyPort,
+ nsIProxyInfo *proxy,
PRFileDesc** fd,
nsISupports** info,
bool forSTARTTLS,
@@ -1609,7 +1608,7 @@ nsSSLIOLayerNewSocket(int32_t family,
PRFileDesc* sock = PR_OpenTCPSocket(family);
if (!sock) return NS_ERROR_OUT_OF_MEMORY;
- nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxyHost, proxyPort,
+ nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxy,
sock, info, forSTARTTLS, flags);
if (NS_FAILED(rv)) {
PR_Close(sock);
@@ -2274,11 +2273,11 @@ loser:
static nsresult
nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS,
- const char* proxyHost, const char* host, int32_t port,
+ bool haveProxy, const char* host, int32_t port,
nsNSSSocketInfo* infoObject)
{
nsNSSShutDownPreventionLock locker;
- if (forSTARTTLS || proxyHost) {
+ if (forSTARTTLS || haveProxy) {
if (SECSuccess != SSL_OptionSet(fd, SSL_SECURITY, false)) {
return NS_ERROR_FAILURE;
}
@@ -2350,8 +2349,7 @@ nsresult
nsSSLIOLayerAddToSocket(int32_t family,
const char* host,
int32_t port,
- const char* proxyHost,
- int32_t proxyPort,
+ nsIProxyInfo* proxy,
PRFileDesc* fd,
nsISupports** info,
bool forSTARTTLS,
@@ -2373,6 +2371,13 @@ nsSSLIOLayerAddToSocket(int32_t family,
infoObject->SetHostName(host);
infoObject->SetPort(port);
+ bool haveProxy = false;
+ if (proxy) {
+ nsCString proxyHost;
+ proxy->GetHost(proxyHost);
+ haveProxy = !proxyHost.IsEmpty();
+ }
+
// A plaintext observer shim is inserted so we can observe some protocol
// details without modifying nss
plaintextLayer = PR_CreateIOLayerStub(nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity,
@@ -2394,7 +2399,7 @@ nsSSLIOLayerAddToSocket(int32_t family,
infoObject->SetFileDescPtr(sslSock);
- rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, proxyHost, host, port,
+ rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, haveProxy, host, port,
infoObject);
if (NS_FAILED(rv))
@@ -2419,7 +2424,7 @@ nsSSLIOLayerAddToSocket(int32_t family,
infoObject->QueryInterface(NS_GET_IID(nsISupports), (void**) (info));
// We are going use a clear connection first //
- if (forSTARTTLS || proxyHost) {
+ if (forSTARTTLS || haveProxy) {
infoObject->SetHandshakeNotPending();
}
diff --git a/security/manager/ssl/src/nsNSSIOLayer.h b/security/manager/ssl/src/nsNSSIOLayer.h
index fca0ce8..6ba745d 100644
--- a/security/manager/ssl/src/nsNSSIOLayer.h
+++ b/security/manager/ssl/src/nsNSSIOLayer.h
@@ -10,6 +10,7 @@
#include "TransportSecurityInfo.h"
#include "nsISSLSocketControl.h"
#include "nsIClientAuthDialogs.h"
+#include "nsIProxyInfo.h"
#include "nsNSSCertificate.h"
#include "nsDataHashtable.h"
#include "nsTHashtable.h"
@@ -202,8 +203,7 @@ private:
nsresult nsSSLIOLayerNewSocket(int32_t family,
const char* host,
int32_t port,
- const char* proxyHost,
- int32_t proxyPort,
+ nsIProxyInfo *proxy,
PRFileDesc** fd,
nsISupports** securityInfo,
bool forSTARTTLS,
@@ -212,8 +212,7 @@ nsresult nsSSLIOLayerNewSocket(int32_t family,
nsresult nsSSLIOLayerAddToSocket(int32_t family,
const char* host,
int32_t port,
- const char* proxyHost,
- int32_t proxyPort,
+ nsIProxyInfo *proxy,
PRFileDesc* fd,
nsISupports** securityInfo,
bool forSTARTTLS,
diff --git a/security/manager/ssl/src/nsSSLSocketProvider.cpp b/security/manager/ssl/src/nsSSLSocketProvider.cpp
index fd37f4c..0666082 100644
--- a/security/manager/ssl/src/nsSSLSocketProvider.cpp
+++ b/security/manager/ssl/src/nsSSLSocketProvider.cpp
@@ -22,8 +22,7 @@ NS_IMETHODIMP
nsSSLSocketProvider::NewSocket(int32_t family,
const char *host,
int32_t port,
- const char *proxyHost,
- int32_t proxyPort,
+ nsIProxyInfo *proxy,
uint32_t flags,
PRFileDesc **_result,
nsISupports **securityInfo)
@@ -31,8 +30,7 @@ nsSSLSocketProvider::NewSocket(int32_t family,
nsresult rv = nsSSLIOLayerNewSocket(family,
host,
port,
- proxyHost,
- proxyPort,
+ proxy,
_result,
securityInfo,
false,
@@ -45,8 +43,7 @@ NS_IMETHODIMP
nsSSLSocketProvider::AddToSocket(int32_t family,
const char *host,
int32_t port,
- const char *proxyHost,
- int32_t proxyPort,
+ nsIProxyInfo *proxy,
uint32_t flags,
PRFileDesc *aSocket,
nsISupports **securityInfo)
@@ -54,8 +51,7 @@ nsSSLSocketProvider::AddToSocket(int32_t family,
nsresult rv = nsSSLIOLayerAddToSocket(family,
host,
port,
- proxyHost,
- proxyPort,
+ proxy,
aSocket,
securityInfo,
false,
diff --git a/security/manager/ssl/src/nsTLSSocketProvider.cpp b/security/manager/ssl/src/nsTLSSocketProvider.cpp
index 029b2c5..09dd2bd 100644
--- a/security/manager/ssl/src/nsTLSSocketProvider.cpp
+++ b/security/manager/ssl/src/nsTLSSocketProvider.cpp
@@ -22,8 +22,7 @@ NS_IMETHODIMP
nsTLSSocketProvider::NewSocket(int32_t family,
const char *host,
int32_t port,
- const char *proxyHost,
- int32_t proxyPort,
+ nsIProxyInfo *proxy,
uint32_t flags,
PRFileDesc **_result,
nsISupports **securityInfo)
@@ -31,8 +30,7 @@ nsTLSSocketProvider::NewSocket(int32_t family,
nsresult rv = nsSSLIOLayerNewSocket(family,
host,
port,
- proxyHost,
- proxyPort,
+ proxy,
_result,
securityInfo,
true,
@@ -46,8 +44,7 @@ NS_IMETHODIMP
nsTLSSocketProvider::AddToSocket(int32_t family,
const char *host,
int32_t port,
- const char *proxyHost,
- int32_t proxyPort,
+ nsIProxyInfo *proxy,
uint32_t flags,
PRFileDesc *aSocket,
nsISupports **securityInfo)
@@ -55,8 +52,7 @@ nsTLSSocketProvider::AddToSocket(int32_t family,
nsresult rv = nsSSLIOLayerAddToSocket(family,
host,
port,
- proxyHost,
- proxyPort,
+ proxy,
aSocket,
securityInfo,
true,
1
0
[tor-browser/tor-browser-31.2.0esr-4.5-1] Bug #3455.1: Allow proxy settings to be set per URL bar domain.
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit 08991021207bcc7c982fa5ae5a9984a12ec7bf5f
Author: Arthur Edelstein <arthuredelstein(a)gmail.com>
Date: Tue Oct 21 02:15:25 2014 -0700
Bug #3455.1: Allow proxy settings to be set per URL bar domain.
---
dom/plugins/base/moz.build | 1 +
dom/plugins/base/nsPluginHost.cpp | 27 ++--
netwerk/base/public/nsIProtocolProxyCallback.idl | 10 +-
netwerk/base/public/nsIProtocolProxyFilter.idl | 34 ++++-
netwerk/base/public/nsIProtocolProxyService.idl | 32 +++-
netwerk/base/public/nsIProtocolProxyService2.idl | 13 +-
netwerk/base/src/nsIOService.cpp | 18 ++-
netwerk/base/src/nsPACMan.cpp | 9 +-
netwerk/base/src/nsPACMan.h | 10 +-
netwerk/base/src/nsProtocolProxyService.cpp | 157 +++++++++++++-------
netwerk/base/src/nsProtocolProxyService.h | 49 ++++--
netwerk/protocol/ftp/nsFtpConnectionThread.cpp | 11 +-
netwerk/protocol/http/HttpBaseChannel.cpp | 10 ++
netwerk/protocol/http/HttpBaseChannel.h | 1 +
netwerk/protocol/http/nsHttpChannel.cpp | 6 +-
netwerk/protocol/http/nsIHttpChannel.idl | 6 +
.../protocol/viewsource/nsViewSourceChannel.cpp | 6 +
netwerk/protocol/websocket/WebSocketChannel.cpp | 4 +-
18 files changed, 281 insertions(+), 123 deletions(-)
diff --git a/dom/plugins/base/moz.build b/dom/plugins/base/moz.build
index ded5fb5..25bae79 100644
--- a/dom/plugins/base/moz.build
+++ b/dom/plugins/base/moz.build
@@ -103,6 +103,7 @@ LOCAL_INCLUDES += [
'/gfx/skia/include/core',
'/layout/generic',
'/layout/xul',
+ '/netwerk/base/src',
'/widget/android',
'/widget/xpwidgets',
'/xpcom/base',
diff --git a/dom/plugins/base/nsPluginHost.cpp b/dom/plugins/base/nsPluginHost.cpp
index bc6bf72..1efe59f 100644
--- a/dom/plugins/base/nsPluginHost.cpp
+++ b/dom/plugins/base/nsPluginHost.cpp
@@ -30,7 +30,7 @@
#include "nsIURL.h"
#include "nsTArray.h"
#include "nsReadableUtils.h"
-#include "nsIProtocolProxyService2.h"
+#include "nsProtocolProxyService.h"
#include "nsIStreamConverterService.h"
#include "nsIFile.h"
#if defined(XP_MACOSX)
@@ -583,32 +583,29 @@ nsresult nsPluginHost::FindProxyForURL(const char* url, char* *result)
}
nsresult res;
- nsCOMPtr<nsIURI> uriIn;
- nsCOMPtr<nsIProtocolProxyService> proxyService;
- nsCOMPtr<nsIProtocolProxyService2> proxyService2;
- nsCOMPtr<nsIIOService> ioService;
-
- proxyService = do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &res);
+ nsCOMPtr<nsIProtocolProxyService> proxyService =
+ do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &res);
if (NS_FAILED(res) || !proxyService)
return res;
- proxyService2 = do_QueryInterface(proxyService, &res);
- if (NS_FAILED(res) || !proxyService2)
- return res;
+ nsRefPtr<nsProtocolProxyService> rawProxyService = do_QueryObject(proxyService);
+ if (!rawProxyService)
+ return NS_ERROR_FAILURE;
- ioService = do_GetService(NS_IOSERVICE_CONTRACTID, &res);
+ nsCOMPtr<nsIIOService> ioService = do_GetService(NS_IOSERVICE_CONTRACTID, &res);
if (NS_FAILED(res) || !ioService)
return res;
- // make an nsURI from the argument url
- res = ioService->NewURI(nsDependentCString(url), nullptr, nullptr, getter_AddRefs(uriIn));
+ // make a temporary channel from the argument url
+ nsCOMPtr<nsIChannel> tempChannel;
+ res = ioService->NewChannel(nsDependentCString(url), nullptr, nullptr, getter_AddRefs(tempChannel));
if (NS_FAILED(res))
return res;
nsCOMPtr<nsIProxyInfo> pi;
- // Remove this with bug 778201
- res = proxyService2->DeprecatedBlockingResolve(uriIn, 0, getter_AddRefs(pi));
+ // Remove this deprecated call in the future (see Bug 778201):
+ res = rawProxyService->DeprecatedBlockingResolve(tempChannel, 0, getter_AddRefs(pi));
if (NS_FAILED(res))
return res;
diff --git a/netwerk/base/public/nsIProtocolProxyCallback.idl b/netwerk/base/public/nsIProtocolProxyCallback.idl
index ca1ab51..96c2181 100644
--- a/netwerk/base/public/nsIProtocolProxyCallback.idl
+++ b/netwerk/base/public/nsIProtocolProxyCallback.idl
@@ -6,7 +6,7 @@
#include "nsISupports.idl"
-interface nsIURI;
+interface nsIChannel;
interface nsIProxyInfo;
interface nsICancelable;
@@ -14,7 +14,7 @@ interface nsICancelable;
* This interface serves as a closure for nsIProtocolProxyService's
* asyncResolve method.
*/
-[scriptable, uuid(a9967200-f95e-45c2-beb3-9b060d874bfd)]
+[scriptable, uuid(fbb6eff6-0cc2-4d99-8d6f-0a12b462bdeb)]
interface nsIProtocolProxyCallback : nsISupports
{
/**
@@ -23,8 +23,8 @@ interface nsIProtocolProxyCallback : nsISupports
*
* @param aRequest
* The value returned from asyncResolve.
- * @param aURI
- * The URI passed to asyncResolve.
+ * @param aChannel
+ * The channel passed to asyncResolve.
* @param aProxyInfo
* The resulting proxy info or null if there is no associated proxy
* info for aURI. As with the result of nsIProtocolProxyService's
@@ -36,7 +36,7 @@ interface nsIProtocolProxyCallback : nsISupports
* indicates the reason for the failure and aProxyInfo will be null.
*/
void onProxyAvailable(in nsICancelable aRequest,
- in nsIURI aURI,
+ in nsIChannel aChannel,
in nsIProxyInfo aProxyInfo,
in nsresult aStatus);
};
diff --git a/netwerk/base/public/nsIProtocolProxyFilter.idl b/netwerk/base/public/nsIProtocolProxyFilter.idl
index 8ad6ca4..8798a49 100644
--- a/netwerk/base/public/nsIProtocolProxyFilter.idl
+++ b/netwerk/base/public/nsIProtocolProxyFilter.idl
@@ -6,6 +6,7 @@
#include "nsISupports.idl"
+interface nsIChannel;
interface nsIProtocolProxyService;
interface nsIProxyInfo;
interface nsIURI;
@@ -13,7 +14,7 @@ interface nsIURI;
/**
* This interface is used to apply filters to the proxies selected for a given
* URI. Use nsIProtocolProxyService::registerFilter to hook up instances of
- * this interface.
+ * this interface. See also nsIProtocolProxyChannelFilter.
*/
[scriptable, uuid(f424abd3-32b4-456c-9f45-b7e3376cb0d1)]
interface nsIProtocolProxyFilter : nsISupports
@@ -40,3 +41,34 @@ interface nsIProtocolProxyFilter : nsISupports
nsIProxyInfo applyFilter(in nsIProtocolProxyService aProxyService,
in nsIURI aURI, in nsIProxyInfo aProxy);
};
+
+/**
+ * This interface is used to apply filters to the proxies selected for a given
+ * channel. Use nsIProtocolProxyService::registerChannelFilter to hook up instances of
+ * this interface. See also nsIProtocolProxyFilter.
+ */
+[scriptable, uuid(245b0880-82c5-4e6e-be6d-bc586aa55a90)]
+interface nsIProtocolProxyChannelFilter : nsISupports
+{
+ /**
+ * This method is called to apply proxy filter rules for the given channel
+ * and proxy object (or list of proxy objects).
+ *
+ * @param aProxyService
+ * A reference to the Protocol Proxy Service. This is passed so that
+ * implementations may easily access methods such as newProxyInfo.
+ * @param aChannel
+ * The channel for which these proxy settings apply.
+ * @param aProxy
+ * The proxy (or list of proxies) that would be used by default for
+ * the given channel. This may be null.
+ *
+ * @return The proxy (or list of proxies) that should be used in place of
+ * aProxy. This can be just be aProxy if the filter chooses not to
+ * modify the proxy. It can also be null to indicate that a direct
+ * connection should be used. Use aProxyService.newProxyInfo to
+ * construct nsIProxyInfo objects.
+ */
+ nsIProxyInfo applyFilter(in nsIProtocolProxyService aProxyService,
+ in nsIChannel aChannel, in nsIProxyInfo aProxy);
+};
diff --git a/netwerk/base/public/nsIProtocolProxyService.idl b/netwerk/base/public/nsIProtocolProxyService.idl
index 526eab8..9365658 100644
--- a/netwerk/base/public/nsIProtocolProxyService.idl
+++ b/netwerk/base/public/nsIProtocolProxyService.idl
@@ -9,6 +9,7 @@
interface nsICancelable;
interface nsIProtocolProxyCallback;
interface nsIProtocolProxyFilter;
+interface nsIProtocolProxyChannelFilter;
interface nsIProxyInfo;
interface nsIChannel;
interface nsIURI;
@@ -17,7 +18,7 @@ interface nsIURI;
* nsIProtocolProxyService provides methods to access information about
* various network proxies.
*/
-[scriptable, uuid(e77c642b-026f-41ce-9b23-f829a6e3f300)]
+[scriptable, uuid(ab363090-c331-489f-aabb-7fe4481795b8)]
interface nsIProtocolProxyService : nsISupports
{
/** Flag 1 << 0 is unused **/
@@ -64,11 +65,11 @@ interface nsIProtocolProxyService : nsISupports
/**
* This method returns via callback a nsIProxyInfo instance that identifies
- * a proxy to be used for loading the given URI. Otherwise, this method returns
+ * a proxy to be used for the given channel. Otherwise, this method returns
* null indicating that a direct connection should be used.
*
- * @param aURI
- * The URI to test.
+ * @param aChannel
+ * The channel for which a proxy is to be found.
* @param aFlags
* A bit-wise combination of the RESOLVE_ flags defined above. Pass
* 0 to specify the default behavior. Any additional bits that do
@@ -94,7 +95,7 @@ interface nsIProtocolProxyService : nsISupports
*
* @see nsIProxiedProtocolHandler::newProxiedChannel
*/
- nsICancelable asyncResolve(in nsIURI aURI, in unsigned long aFlags,
+ nsICancelable asyncResolve(in nsIChannel aChannel, in unsigned long aFlags,
in nsIProtocolProxyCallback aCallback);
/**
@@ -191,6 +192,18 @@ interface nsIProtocolProxyService : nsISupports
in unsigned long aPosition);
/**
+ * Similar to registerFilter, but accepts an nsIProtocolProxyChannelFilter,
+ * which selects proxies according to channel rather than URI.
+ *
+ * @param aFilter
+ * The nsIProtocolProxyChannelFilter instance to be registered.
+ * @param aPosition
+ * The position of the filter.
+ */
+ void registerChannelFilter(in nsIProtocolProxyChannelFilter aFilter,
+ in unsigned long aPosition);
+
+ /**
* This method may be used to unregister a proxy filter instance. All
* filters will be automatically unregistered at XPCOM shutdown.
*
@@ -199,6 +212,15 @@ interface nsIProtocolProxyService : nsISupports
*/
void unregisterFilter(in nsIProtocolProxyFilter aFilter);
+ /**
+ * This method may be used to unregister a proxy channel filter instance. All
+ * filters will be automatically unregistered at XPCOM shutdown.
+ *
+ * @param aFilter
+ * The nsIProtocolProxyChannelFilter instance to be unregistered.
+ */
+ void unregisterChannelFilter(in nsIProtocolProxyChannelFilter aFilter);
+
/**
* These values correspond to the possible integer values for the
* network.proxy.type preference.
diff --git a/netwerk/base/public/nsIProtocolProxyService2.idl b/netwerk/base/public/nsIProtocolProxyService2.idl
index cb39a33..9e4f548 100644
--- a/netwerk/base/public/nsIProtocolProxyService2.idl
+++ b/netwerk/base/public/nsIProtocolProxyService2.idl
@@ -9,7 +9,7 @@
/**
* An extension of nsIProtocolProxyService
*/
-[scriptable, uuid(bb52e571-4a0e-4363-83d0-52034910dd14)]
+[scriptable, uuid(b2e5b2c0-e21e-4845-b336-be6d60a38951)]
interface nsIProtocolProxyService2 : nsIProtocolProxyService
{
/**
@@ -18,21 +18,12 @@ interface nsIProtocolProxyService2 : nsIProtocolProxyService
*/
void reloadPAC();
- /**
- * This exists so Java(tm) can migrate to an asynchronous interface.
- * Do not use this unless you are the plugin interface, and even then you
- * ought to feel horribly guilty because you will create main thread jank.
- *
- * No documentation - it is deprecated!
- **/
- nsIProxyInfo deprecatedBlockingResolve(in nsIURI aURI, in unsigned long aFlags);
-
/**
* This method is identical to asyncResolve() except it may execute the
* callback function immediately (i.e from the stack of asyncResolve2()) if
* it is immediately ready to run. The nsICancelable return value will be
* null in that case.
*/
- nsICancelable asyncResolve2(in nsIURI aURI, in unsigned long aFlags,
+ nsICancelable asyncResolve2(in nsIChannel aChannel, in unsigned long aFlags,
in nsIProtocolProxyCallback aCallback);
};
diff --git a/netwerk/base/src/nsIOService.cpp b/netwerk/base/src/nsIOService.cpp
index b64e7d3..99efa57 100644
--- a/netwerk/base/src/nsIOService.cpp
+++ b/netwerk/base/src/nsIOService.cpp
@@ -1197,7 +1197,7 @@ private:
NS_IMPL_ISUPPORTS(IOServiceProxyCallback, nsIProtocolProxyCallback)
NS_IMETHODIMP
-IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIURI *aURI,
+IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIChannel *channel,
nsIProxyInfo *pi, nsresult status)
{
// Checking proxy status for speculative connect
@@ -1209,8 +1209,13 @@ IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIURI *aURI,
return NS_OK;
}
+ nsCOMPtr<nsIURI> uri;
+ nsresult rv = channel->GetURI(getter_AddRefs(uri));
+ if (NS_FAILED(rv))
+ return NS_OK;
+
nsAutoCString scheme;
- nsresult rv = aURI->GetScheme(scheme);
+ rv = uri->GetScheme(scheme);
if (NS_FAILED(rv))
return NS_OK;
@@ -1225,7 +1230,7 @@ IOServiceProxyCallback::OnProxyAvailable(nsICancelable *request, nsIURI *aURI,
if (!speculativeHandler)
return NS_OK;
- speculativeHandler->SpeculativeConnect(aURI,
+ speculativeHandler->SpeculativeConnect(uri,
mCallbacks);
return NS_OK;
}
@@ -1243,8 +1248,13 @@ nsIOService::SpeculativeConnect(nsIURI *aURI,
if (NS_FAILED(rv))
return rv;
+ nsCOMPtr<nsIChannel> channel;
+ rv = NewChannelFromURI(aURI, getter_AddRefs(channel));
+ if (NS_FAILED(rv))
+ return rv;
+
nsCOMPtr<nsICancelable> cancelable;
nsRefPtr<IOServiceProxyCallback> callback =
new IOServiceProxyCallback(aCallbacks, this);
- return pps->AsyncResolve(aURI, 0, callback, getter_AddRefs(cancelable));
+ return pps->AsyncResolve(channel, 0, callback, getter_AddRefs(cancelable));
}
diff --git a/netwerk/base/src/nsPACMan.cpp b/netwerk/base/src/nsPACMan.cpp
index 81bc17e..e8b0b2d 100644
--- a/netwerk/base/src/nsPACMan.cpp
+++ b/netwerk/base/src/nsPACMan.cpp
@@ -320,8 +320,8 @@ nsPACMan::Shutdown()
}
nsresult
-nsPACMan::AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback,
- bool mainThreadResponse)
+nsPACMan::AsyncGetProxyForChannel(nsIChannel *channel, nsPACManCallback *callback,
+ bool mainThreadResponse)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "wrong thread");
if (mShutdown)
@@ -332,6 +332,11 @@ nsPACMan::AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback,
TimeStamp::Now() > mScheduledReload)
LoadPACFromURI(EmptyCString());
+ nsCOMPtr<nsIURI> uri;
+ nsresult rv = channel->GetURI(getter_AddRefs(uri));
+ if (NS_FAILED(rv))
+ return rv;
+
nsRefPtr<PendingPACQuery> query =
new PendingPACQuery(this, uri, callback, mainThreadResponse);
diff --git a/netwerk/base/src/nsPACMan.h b/netwerk/base/src/nsPACMan.h
index 410ae5641..6f95d97 100644
--- a/netwerk/base/src/nsPACMan.h
+++ b/netwerk/base/src/nsPACMan.h
@@ -27,13 +27,13 @@ class nsIThread;
class WaitForThreadShutdown;
/**
- * This class defines a callback interface used by AsyncGetProxyForURI.
+ * This class defines a callback interface used by AsyncGetProxyForChannel.
*/
class NS_NO_VTABLE nsPACManCallback : public nsISupports
{
public:
/**
- * This method is invoked on the same thread that called AsyncGetProxyForURI.
+ * This method is invoked on the same thread that called AsyncGetProxyForChannel.
*
* @param status
* This parameter indicates whether or not the PAC query succeeded.
@@ -101,14 +101,14 @@ public:
* will queue up the request, and complete it once the PAC file has been
* loaded.
*
- * @param uri
- * The URI to query.
+ * @param channel
+ * The channel to query.
* @param callback
* The callback to run once the PAC result is available.
* @param mustCallbackOnMainThread
* If set to false the callback can be made from the PAC thread
*/
- nsresult AsyncGetProxyForURI(nsIURI *uri, nsPACManCallback *callback,
+ nsresult AsyncGetProxyForChannel(nsIChannel *channel, nsPACManCallback *callback,
bool mustCallbackOnMainThread);
/**
diff --git a/netwerk/base/src/nsProtocolProxyService.cpp b/netwerk/base/src/nsProtocolProxyService.cpp
index 98ea68b..3878c58d 100644
--- a/netwerk/base/src/nsProtocolProxyService.cpp
+++ b/netwerk/base/src/nsProtocolProxyService.cpp
@@ -14,6 +14,7 @@
#include "nsIObserverService.h"
#include "nsIProtocolHandler.h"
#include "nsIProtocolProxyCallback.h"
+#include "nsIChannel.h"
#include "nsICancelable.h"
#include "nsIDNSService.h"
#include "nsPIDNSService.h"
@@ -67,7 +68,7 @@ struct nsProtocolInfo {
//----------------------------------------------------------------------------
// The nsPACManCallback portion of this implementation should be run
-// on the main thread - so call nsPACMan::AsyncGetProxyForURI() with
+// on the main thread - so call nsPACMan::AsyncGetProxyForChannel() with
// a true mainThreadResponse parameter.
class nsAsyncResolveRequest MOZ_FINAL : public nsIRunnable
, public nsPACManCallback
@@ -76,7 +77,7 @@ class nsAsyncResolveRequest MOZ_FINAL : public nsIRunnable
public:
NS_DECL_THREADSAFE_ISUPPORTS
- nsAsyncResolveRequest(nsProtocolProxyService *pps, nsIURI *uri,
+ nsAsyncResolveRequest(nsProtocolProxyService *pps, nsIChannel *channel,
uint32_t aResolveFlags,
nsIProtocolProxyCallback *callback)
: mStatus(NS_OK)
@@ -84,7 +85,7 @@ public:
, mResolveFlags(aResolveFlags)
, mPPS(pps)
, mXPComPPS(pps)
- , mURI(uri)
+ , mChannel(channel)
, mCallback(callback)
{
NS_ASSERTION(mCallback, "null callback");
@@ -100,9 +101,9 @@ public:
nsCOMPtr<nsIThread> mainThread;
NS_GetMainThread(getter_AddRefs(mainThread));
- if (mURI) {
- nsIURI *forgettable;
- mURI.forget(&forgettable);
+ if (mChannel) {
+ nsIChannel *forgettable;
+ mChannel.forget(&forgettable);
NS_ProxyRelease(mainThread, forgettable, false);
}
@@ -207,19 +208,21 @@ private:
if (NS_SUCCEEDED(mStatus) && !mProxyInfo && !mPACString.IsEmpty()) {
mPPS->ProcessPACString(mPACString, mResolveFlags,
getter_AddRefs(mProxyInfo));
+ nsCOMPtr<nsIURI> uri;
+ mChannel->GetURI(getter_AddRefs(uri));
// Now apply proxy filters
nsProtocolInfo info;
- mStatus = mPPS->GetProtocolInfo(mURI, &info);
+ mStatus = mPPS->GetProtocolInfo(uri, &info);
if (NS_SUCCEEDED(mStatus))
- mPPS->ApplyFilters(mURI, info, mProxyInfo);
+ mPPS->ApplyFilters(mChannel, info, mProxyInfo);
else
mProxyInfo = nullptr;
LOG(("pac thread callback %s\n", mPACString.get()));
if (NS_SUCCEEDED(mStatus))
mPPS->MaybeDisableDNSPrefetch(mProxyInfo);
- mCallback->OnProxyAvailable(this, mURI, mProxyInfo, mStatus);
+ mCallback->OnProxyAvailable(this, mChannel, mProxyInfo, mStatus);
}
else if (NS_SUCCEEDED(mStatus) && !mPACURL.IsEmpty()) {
LOG(("pac thread callback indicates new pac file load\n"));
@@ -229,12 +232,12 @@ private:
if (NS_SUCCEEDED(rv)) {
// now that the load is triggered, we can resubmit the query
nsRefPtr<nsAsyncResolveRequest> newRequest =
- new nsAsyncResolveRequest(mPPS, mURI, mResolveFlags, mCallback);
- rv = mPPS->mPACMan->AsyncGetProxyForURI(mURI, newRequest, true);
+ new nsAsyncResolveRequest(mPPS, mChannel, mResolveFlags, mCallback);
+ rv = mPPS->mPACMan->AsyncGetProxyForChannel(mChannel, newRequest, true);
}
if (NS_FAILED(rv))
- mCallback->OnProxyAvailable(this, mURI, nullptr, rv);
+ mCallback->OnProxyAvailable(this, mChannel, nullptr, rv);
// do not call onproxyavailable() in SUCCESS case - the newRequest will
// take care of that
@@ -243,7 +246,7 @@ private:
LOG(("pac thread callback did not provide information %X\n", mStatus));
if (NS_SUCCEEDED(mStatus))
mPPS->MaybeDisableDNSPrefetch(mProxyInfo);
- mCallback->OnProxyAvailable(this, mURI, mProxyInfo, mStatus);
+ mCallback->OnProxyAvailable(this, mChannel, mProxyInfo, mStatus);
}
// We are on the main thread now and don't need these any more so
@@ -252,7 +255,7 @@ private:
mCallback = nullptr; // in case the callback holds an owning ref to us
mPPS = nullptr;
mXPComPPS = nullptr;
- mURI = nullptr;
+ mChannel = nullptr;
mProxyInfo = nullptr;
}
@@ -266,7 +269,7 @@ private:
nsProtocolProxyService *mPPS;
nsCOMPtr<nsIProtocolProxyService> mXPComPPS;
- nsCOMPtr<nsIURI> mURI;
+ nsCOMPtr<nsIChannel> mChannel;
nsCOMPtr<nsIProtocolProxyCallback> mCallback;
nsCOMPtr<nsIProxyInfo> mProxyInfo;
};
@@ -964,7 +967,7 @@ nsProtocolProxyService::ReloadPAC()
// The nsPACManCallback portion of this implementation should be run
// off the main thread, because it uses a condvar for signaling and
// the main thread is blocking on that condvar -
-// so call nsPACMan::AsyncGetProxyForURI() with
+// so call nsPACMan::AsyncGetProxyForChannel() with
// a false mainThreadResponse parameter.
class nsAsyncBridgeRequest MOZ_FINAL : public nsPACManCallback
{
@@ -1010,16 +1013,19 @@ private:
};
NS_IMPL_ISUPPORTS0(nsAsyncBridgeRequest)
-// nsIProtocolProxyService2
+// nsProtocolProxyService
NS_IMETHODIMP
-nsProtocolProxyService::DeprecatedBlockingResolve(nsIURI *aURI,
+nsProtocolProxyService::DeprecatedBlockingResolve(nsIChannel *aChannel,
uint32_t aFlags,
nsIProxyInfo **retval)
{
- NS_ENSURE_ARG_POINTER(aURI);
+ NS_ENSURE_ARG_POINTER(aChannel);
+
+ nsCOMPtr<nsIURI> uri;
+ aChannel->GetURI(getter_AddRefs(uri));
nsProtocolInfo info;
- nsresult rv = GetProtocolInfo(aURI, &info);
+ nsresult rv = GetProtocolInfo(uri, &info);
if (NS_FAILED(rv))
return rv;
@@ -1030,12 +1036,12 @@ nsProtocolProxyService::DeprecatedBlockingResolve(nsIURI *aURI,
// but if neither of them are in use, we can just do the work
// right here and directly invoke the callback
- rv = Resolve_Internal(aURI, info, aFlags, &usePACThread, getter_AddRefs(pi));
+ rv = Resolve_Internal(aChannel, info, aFlags, &usePACThread, getter_AddRefs(pi));
if (NS_FAILED(rv))
return rv;
if (!usePACThread || !mPACMan) {
- ApplyFilters(aURI, info, pi);
+ ApplyFilters(aChannel, info, pi);
pi.forget(retval);
return NS_OK;
}
@@ -1044,7 +1050,7 @@ nsProtocolProxyService::DeprecatedBlockingResolve(nsIURI *aURI,
// code, but block this thread on that completion.
nsRefPtr<nsAsyncBridgeRequest> ctx = new nsAsyncBridgeRequest();
ctx->Lock();
- if (NS_SUCCEEDED(mPACMan->AsyncGetProxyForURI(aURI, ctx, false))) {
+ if (NS_SUCCEEDED(mPACMan->AsyncGetProxyForChannel(aChannel, ctx, false))) {
// this can really block the main thread, so cap it at 3 seconds
ctx->Wait();
}
@@ -1060,7 +1066,7 @@ nsProtocolProxyService::DeprecatedBlockingResolve(nsIURI *aURI,
if (!ctx->mPACString.IsEmpty()) {
LOG(("sync pac thread callback %s\n", ctx->mPACString.get()));
ProcessPACString(ctx->mPACString, 0, getter_AddRefs(pi));
- ApplyFilters(aURI, info, pi);
+ ApplyFilters(aChannel, info, pi);
pi.forget(retval);
return NS_OK;
}
@@ -1084,17 +1090,20 @@ nsProtocolProxyService::DeprecatedBlockingResolve(nsIURI *aURI,
}
nsresult
-nsProtocolProxyService::AsyncResolveInternal(nsIURI *uri, uint32_t flags,
+nsProtocolProxyService::AsyncResolveInternal(nsIChannel *channel, uint32_t flags,
nsIProtocolProxyCallback *callback,
nsICancelable **result,
bool isSyncOK)
{
- NS_ENSURE_ARG_POINTER(uri);
+ NS_ENSURE_ARG_POINTER(channel);
NS_ENSURE_ARG_POINTER(callback);
+ nsCOMPtr<nsIURI> uri;
+ channel->GetURI(getter_AddRefs(uri));
+
*result = nullptr;
nsRefPtr<nsAsyncResolveRequest> ctx =
- new nsAsyncResolveRequest(this, uri, flags, callback);
+ new nsAsyncResolveRequest(this, channel, flags, callback);
nsProtocolInfo info;
nsresult rv = GetProtocolInfo(uri, &info);
@@ -1108,13 +1117,13 @@ nsProtocolProxyService::AsyncResolveInternal(nsIURI *uri, uint32_t flags,
// but if neither of them are in use, we can just do the work
// right here and directly invoke the callback
- rv = Resolve_Internal(uri, info, flags, &usePACThread, getter_AddRefs(pi));
+ rv = Resolve_Internal(channel, info, flags, &usePACThread, getter_AddRefs(pi));
if (NS_FAILED(rv))
return rv;
if (!usePACThread || !mPACMan) {
// we can do it locally
- ApplyFilters(uri, info, pi);
+ ApplyFilters(channel, info, pi);
ctx->SetResult(NS_OK, pi);
if (isSyncOK) {
ctx->Run();
@@ -1129,7 +1138,7 @@ nsProtocolProxyService::AsyncResolveInternal(nsIURI *uri, uint32_t flags,
// else kick off a PAC thread query
- rv = mPACMan->AsyncGetProxyForURI(uri, ctx, true);
+ rv = mPACMan->AsyncGetProxyForChannel(channel, ctx, true);
if (NS_SUCCEEDED(rv))
ctx.forget(result);
return rv;
@@ -1137,19 +1146,19 @@ nsProtocolProxyService::AsyncResolveInternal(nsIURI *uri, uint32_t flags,
// nsIProtocolProxyService
NS_IMETHODIMP
-nsProtocolProxyService::AsyncResolve2(nsIURI *uri, uint32_t flags,
+nsProtocolProxyService::AsyncResolve2(nsIChannel *channel, uint32_t flags,
nsIProtocolProxyCallback *callback,
nsICancelable **result)
{
- return AsyncResolveInternal(uri, flags, callback, result, true);
+ return AsyncResolveInternal(channel, flags, callback, result, true);
}
NS_IMETHODIMP
-nsProtocolProxyService::AsyncResolve(nsIURI *uri, uint32_t flags,
+nsProtocolProxyService::AsyncResolve(nsIChannel *channel, uint32_t flags,
nsIProtocolProxyCallback *callback,
nsICancelable **result)
{
- return AsyncResolveInternal(uri, flags, callback, result, false);
+ return AsyncResolveInternal(channel, flags, callback, result, false);
}
NS_IMETHODIMP
@@ -1221,16 +1230,9 @@ nsProtocolProxyService::GetFailoverForProxy(nsIProxyInfo *aProxy,
return NS_OK;
}
-NS_IMETHODIMP
-nsProtocolProxyService::RegisterFilter(nsIProtocolProxyFilter *filter,
- uint32_t position)
+nsresult
+nsProtocolProxyService::InsertFilterLink(FilterLink *link, uint32_t position)
{
- UnregisterFilter(filter); // remove this filter if we already have it
-
- FilterLink *link = new FilterLink(position, filter);
- if (!link)
- return NS_ERROR_OUT_OF_MEMORY;
-
if (!mFilters) {
mFilters = link;
return NS_OK;
@@ -1258,11 +1260,32 @@ nsProtocolProxyService::RegisterFilter(nsIProtocolProxyFilter *filter,
}
NS_IMETHODIMP
-nsProtocolProxyService::UnregisterFilter(nsIProtocolProxyFilter *filter)
+nsProtocolProxyService::RegisterFilter(nsIProtocolProxyFilter *filter,
+ uint32_t position)
{
- // QI to nsISupports so we can safely test object identity.
- nsCOMPtr<nsISupports> givenObject = do_QueryInterface(filter);
+ UnregisterFilter(filter); // remove this filter if we already have it
+
+ FilterLink *link = new FilterLink(position, filter);
+ if (!link)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return InsertFilterLink(link, position);
+}
+NS_IMETHODIMP
+nsProtocolProxyService::RegisterChannelFilter(nsIProtocolProxyChannelFilter *channelFilter,
+ uint32_t position)
+{
+ UnregisterChannelFilter(channelFilter); // remove this filter if we already have it
+
+ FilterLink *link = new FilterLink(position, channelFilter);
+ if (!link)
+ return NS_ERROR_OUT_OF_MEMORY;
+ return InsertFilterLink(link, position);
+}
+
+nsresult
+nsProtocolProxyService::RemoveFilterLink(nsISupports* givenObject)
+{
FilterLink *last = nullptr;
for (FilterLink *iter = mFilters; iter; iter = iter->next) {
nsCOMPtr<nsISupports> object = do_QueryInterface(iter->filter);
@@ -1283,6 +1306,20 @@ nsProtocolProxyService::UnregisterFilter(nsIProtocolProxyFilter *filter)
}
NS_IMETHODIMP
+nsProtocolProxyService::UnregisterFilter(nsIProtocolProxyFilter *filter) {
+ // QI to nsISupports so we can safely test object identity.
+ nsCOMPtr<nsISupports> givenObject = do_QueryInterface(filter);
+ return RemoveFilterLink(givenObject);
+}
+
+NS_IMETHODIMP
+nsProtocolProxyService::UnregisterChannelFilter(nsIProtocolProxyChannelFilter *channelFilter) {
+ // QI to nsISupports so we can safely test object identity.
+ nsCOMPtr<nsISupports> givenObject = do_QueryInterface(channelFilter);
+ return RemoveFilterLink(givenObject);
+}
+
+NS_IMETHODIMP
nsProtocolProxyService::GetProxyConfigType(uint32_t* aProxyConfigType)
{
*aProxyConfigType = mProxyConfig;
@@ -1489,13 +1526,13 @@ nsProtocolProxyService::NewProxyInfo_Internal(const char *aType,
}
nsresult
-nsProtocolProxyService::Resolve_Internal(nsIURI *uri,
+nsProtocolProxyService::Resolve_Internal(nsIChannel *channel,
const nsProtocolInfo &info,
uint32_t flags,
bool *usePACThread,
nsIProxyInfo **result)
{
- NS_ENSURE_ARG_POINTER(uri);
+ NS_ENSURE_ARG_POINTER(channel);
nsresult rv = SetupPACThread();
if (NS_FAILED(rv))
return rv;
@@ -1506,6 +1543,9 @@ nsProtocolProxyService::Resolve_Internal(nsIURI *uri,
if (!(info.flags & nsIProtocolHandler::ALLOWS_PROXY))
return NS_OK; // Can't proxy this (filters may not override)
+ nsCOMPtr<nsIURI> uri;
+ channel->GetURI(getter_AddRefs(uri));
+
// See bug #586908.
// Avoid endless loop if |uri| is the current PAC-URI. Returning OK
// here means that we will not use a proxy for this connection.
@@ -1675,7 +1715,7 @@ nsProtocolProxyService::MaybeDisableDNSPrefetch(nsIProxyInfo *aProxy)
}
void
-nsProtocolProxyService::ApplyFilters(nsIURI *uri, const nsProtocolInfo &info,
+nsProtocolProxyService::ApplyFilters(nsIChannel *channel, const nsProtocolInfo &info,
nsIProxyInfo **list)
{
if (!(info.flags & nsIProtocolHandler::ALLOWS_PROXY))
@@ -1690,9 +1730,22 @@ nsProtocolProxyService::ApplyFilters(nsIURI *uri, const nsProtocolInfo &info,
for (FilterLink *iter = mFilters; iter; iter = iter->next) {
PruneProxyInfo(info, list);
-
- rv = iter->filter->ApplyFilter(this, uri, *list,
- getter_AddRefs(result));
+ if (!!iter->filter) {
+ nsCOMPtr<nsIURI> uri;
+ channel->GetURI(getter_AddRefs(uri));
+ if (!!uri) {
+ nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
+ nsCOMPtr<nsIURI> proxyURI = nullptr;
+ if (!!httpChannel) {
+ httpChannel->GetProxyURI(getter_AddRefs(proxyURI));
+ }
+ rv = iter->filter->ApplyFilter(this, proxyURI ? proxyURI : uri, *list,
+ getter_AddRefs(result));
+ }
+ } else if (!!iter->channelFilter) {
+ rv = iter->channelFilter->ApplyFilter(this, channel, *list,
+ getter_AddRefs(result));
+ }
if (NS_FAILED(rv))
continue;
result.swap(*list);
diff --git a/netwerk/base/src/nsProtocolProxyService.h b/netwerk/base/src/nsProtocolProxyService.h
index 4108e30..9ef68b9 100644
--- a/netwerk/base/src/nsProtocolProxyService.h
+++ b/netwerk/base/src/nsProtocolProxyService.h
@@ -27,6 +27,12 @@ class nsIPrefBranch;
class nsISystemProxySettings;
class nsPACMan;
+// CID for the nsProtocolProxyService class
+// 091eedd8-8bae-4fe3-ad62-0c87351e640d
+#define NS_PROTOCOL_PROXY_SERVICE_IMPL_CID \
+{ 0x091eedd8, 0x8bae, 0x4fe3, \
+ { 0xad, 0x62, 0x0c, 0x87, 0x35, 0x1e, 0x64, 0x0d } }
+
class nsProtocolProxyService MOZ_FINAL : public nsIProtocolProxyService2
, public nsIObserver
{
@@ -36,9 +42,14 @@ public:
NS_DECL_NSIPROTOCOLPROXYSERVICE
NS_DECL_NSIOBSERVER
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_PROTOCOL_PROXY_SERVICE_IMPL_CID)
+
nsProtocolProxyService() NS_HIDDEN;
NS_HIDDEN_(nsresult) Init();
+ nsresult DeprecatedBlockingResolve(nsIChannel *aChannel,
+ uint32_t aFlags,
+ nsIProxyInfo **retval);
protected:
friend class nsAsyncResolveRequest;
@@ -192,8 +203,8 @@ protected:
* caller with either the proxy info result or a flag to instruct the
* caller to use PAC instead.
*
- * @param uri
- * The URI to test.
+ * @param channel
+ * The channel to test.
* @param info
* Information about the URI's protocol.
* @param flags
@@ -204,7 +215,7 @@ protected:
* @param result
* The resulting proxy info or null.
*/
- NS_HIDDEN_(nsresult) Resolve_Internal(nsIURI *uri,
+ NS_HIDDEN_(nsresult) Resolve_Internal(nsIChannel *channel,
const nsProtocolInfo &info,
uint32_t flags,
bool *usePAC,
@@ -214,26 +225,26 @@ protected:
* This method applies the registered filters to the given proxy info
* list, and returns a possibly modified list.
*
- * @param uri
- * The URI corresponding to this proxy info list.
+ * @param channel
+ * The channel corresponding to this proxy info list.
* @param info
* Information about the URI's protocol.
* @param proxyInfo
* The proxy info list to be modified. This is an inout param.
*/
- NS_HIDDEN_(void) ApplyFilters(nsIURI *uri, const nsProtocolInfo &info,
+ NS_HIDDEN_(void) ApplyFilters(nsIChannel *channel, const nsProtocolInfo &info,
nsIProxyInfo **proxyInfo);
/**
* This method is a simple wrapper around ApplyFilters that takes the
* proxy info list inout param as a nsCOMPtr.
*/
- inline void ApplyFilters(nsIURI *uri, const nsProtocolInfo &info,
+ inline void ApplyFilters(nsIChannel *channel, const nsProtocolInfo &info,
nsCOMPtr<nsIProxyInfo> &proxyInfo)
{
nsIProxyInfo *pi = nullptr;
proxyInfo.swap(pi);
- ApplyFilters(uri, info, &pi);
+ ApplyFilters(channel, info, &pi);
proxyInfo.swap(pi);
}
@@ -317,19 +328,27 @@ protected:
}
};
- // This structure is allocated for each registered nsIProtocolProxyFilter.
+ // An instance of this struct is allocated for each registered
+ // nsIProtocolProxyFilter and each nsIProtocolProxyChannelFilter.
struct FilterLink {
struct FilterLink *next;
uint32_t position;
- nsCOMPtr<nsIProtocolProxyFilter> filter;
-
+ nsCOMPtr<nsIProtocolProxyFilter> filter;
+ nsCOMPtr<nsIProtocolProxyChannelFilter> channelFilter;
FilterLink(uint32_t p, nsIProtocolProxyFilter *f)
- : next(nullptr), position(p), filter(f) {}
-
+ : next(nullptr), position(p), filter(f), channelFilter(nullptr) {}
+ FilterLink(uint32_t p, nsIProtocolProxyChannelFilter *cf)
+ : next(nullptr), position(p), filter(nullptr), channelFilter(cf) {}
// Chain deletion to simplify cleaning up the filter links
~FilterLink() { if (next) delete next; }
};
+private:
+ // Private methods to insert and remove FilterLinks from the FilterLink chain.
+ nsresult InsertFilterLink(FilterLink *link, uint32_t position);
+ nsresult RemoveFilterLink(nsISupports *givenObject);
+
+protected:
// Indicates if local hosts (plain hostnames, no dots) should use the proxy
bool mFilterLocalHosts;
@@ -364,11 +383,13 @@ protected:
int32_t mFailedProxyTimeout;
private:
- nsresult AsyncResolveInternal(nsIURI *uri, uint32_t flags,
+ nsresult AsyncResolveInternal(nsIChannel *channel, uint32_t flags,
nsIProtocolProxyCallback *callback,
nsICancelable **result,
bool isSyncOK);
};
+NS_DEFINE_STATIC_IID_ACCESSOR(nsProtocolProxyService, NS_PROTOCOL_PROXY_SERVICE_IMPL_CID)
+
#endif // !nsProtocolProxyService_h__
diff --git a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
index 6d8d9f1..5073dbb 100644
--- a/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
+++ b/netwerk/protocol/ftp/nsFtpConnectionThread.cpp
@@ -1872,7 +1872,7 @@ nsFtpState::Init(nsFtpChannel *channel)
do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID);
if (pps && !mChannel->ProxyInfo()) {
- pps->AsyncResolve(mChannel->URI(), 0, this,
+ pps->AsyncResolve(mChannel, 0, this,
getter_AddRefs(mProxyRequest));
}
@@ -2358,7 +2358,7 @@ nsFtpState::CloseWithStatus(nsresult status)
}
static nsresult
-CreateHTTPProxiedChannel(nsIURI *uri, nsIProxyInfo *pi, nsIChannel **newChannel)
+CreateHTTPProxiedChannel(nsIChannel *channel, nsIProxyInfo *pi, nsIChannel **newChannel)
{
nsresult rv;
nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
@@ -2374,11 +2374,14 @@ CreateHTTPProxiedChannel(nsIURI *uri, nsIProxyInfo *pi, nsIChannel **newChannel)
if (NS_FAILED(rv))
return rv;
+ nsCOMPtr<nsIURI> uri;
+ channel->GetURI(getter_AddRefs(uri));
+
return pph->NewProxiedChannel(uri, pi, 0, nullptr, newChannel);
}
NS_IMETHODIMP
-nsFtpState::OnProxyAvailable(nsICancelable *request, nsIURI *uri,
+nsFtpState::OnProxyAvailable(nsICancelable *request, nsIChannel *channel,
nsIProxyInfo *pi, nsresult status)
{
mProxyRequest = nullptr;
@@ -2395,7 +2398,7 @@ nsFtpState::OnProxyAvailable(nsICancelable *request, nsIURI *uri,
LOG(("FTP:(%p) Configured to use a HTTP proxy channel\n", this));
nsCOMPtr<nsIChannel> newChannel;
- if (NS_SUCCEEDED(CreateHTTPProxiedChannel(uri, pi,
+ if (NS_SUCCEEDED(CreateHTTPProxiedChannel(channel, pi,
getter_AddRefs(newChannel))) &&
NS_SUCCEEDED(mChannel->Redirect(newChannel,
nsIChannelEventSink::REDIRECT_INTERNAL,
diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp
index 40123da..64b202a 100644
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -68,6 +68,7 @@ HttpBaseChannel::HttpBaseChannel()
, mContentDispositionHint(UINT32_MAX)
, mHttpHandler(gHttpHandler)
, mRedirectCount(0)
+ , mProxyURI(nullptr)
{
LOG(("Creating HttpBaseChannel @%x\n", this));
@@ -1075,6 +1076,15 @@ HttpBaseChannel::SetReferrer(nsIURI *referrer)
}
NS_IMETHODIMP
+HttpBaseChannel::GetProxyURI(nsIURI** proxyURI)
+{
+ NS_ENSURE_ARG_POINTER(proxyURI);
+ *proxyURI = mProxyURI;
+ NS_IF_ADDREF(*proxyURI);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
HttpBaseChannel::GetRequestHeader(const nsACString& aHeader,
nsACString& aValue)
{
diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h
index e177a39..abaf789 100644
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -115,6 +115,7 @@ public:
NS_IMETHOD SetRequestMethod(const nsACString& aMethod);
NS_IMETHOD GetReferrer(nsIURI **referrer);
NS_IMETHOD SetReferrer(nsIURI *referrer);
+ NS_IMETHOD GetProxyURI(nsIURI **proxyURI);
NS_IMETHOD GetRequestHeader(const nsACString& aHeader, nsACString& aValue);
NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
const nsACString& aValue, bool aMerge);
diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp
index 6449769..41ef8bb 100644
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -1823,10 +1823,10 @@ nsHttpChannel::ResolveProxy()
// then it is ok to use that version.
nsCOMPtr<nsIProtocolProxyService2> pps2 = do_QueryInterface(pps);
if (pps2) {
- rv = pps2->AsyncResolve2(mProxyURI ? mProxyURI : mURI, mProxyResolveFlags,
+ rv = pps2->AsyncResolve2(this, mProxyResolveFlags,
this, getter_AddRefs(mProxyRequest));
} else {
- rv = pps->AsyncResolve(mProxyURI ? mProxyURI : mURI, mProxyResolveFlags,
+ rv = pps->AsyncResolve(this, mProxyResolveFlags,
this, getter_AddRefs(mProxyRequest));
}
@@ -4707,7 +4707,7 @@ nsHttpChannel::SetPriority(int32_t value)
//-----------------------------------------------------------------------------
NS_IMETHODIMP
-nsHttpChannel::OnProxyAvailable(nsICancelable *request, nsIURI *uri,
+nsHttpChannel::OnProxyAvailable(nsICancelable *request, nsIChannel *channel,
nsIProxyInfo *pi, nsresult status)
{
LOG(("nsHttpChannel::OnProxyAvailable [this=%p pi=%p status=%x mStatus=%x]\n",
diff --git a/netwerk/protocol/http/nsIHttpChannel.idl b/netwerk/protocol/http/nsIHttpChannel.idl
index abb2ee4..24df18b 100644
--- a/netwerk/protocol/http/nsIHttpChannel.idl
+++ b/netwerk/protocol/http/nsIHttpChannel.idl
@@ -56,6 +56,12 @@ interface nsIHttpChannel : nsIChannel
attribute nsIURI referrer;
/**
+ * Read the proxy URI, which, if non-null, will be used to resolve
+ * proxies for this channel.
+ */
+ readonly attribute nsIURI proxyURI;
+
+ /**
* Get the value of a particular request header.
*
* @param aHeader
diff --git a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
index f92c36e..350c920 100644
--- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
+++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp
@@ -115,6 +115,12 @@ nsViewSourceChannel::GetName(nsACString &result)
}
NS_IMETHODIMP
+nsViewSourceChannel::GetProxyURI(nsIURI** proxyURI)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
nsViewSourceChannel::IsPending(bool *result)
{
NS_ENSURE_TRUE(mChannel, NS_ERROR_FAILURE);
diff --git a/netwerk/protocol/websocket/WebSocketChannel.cpp b/netwerk/protocol/websocket/WebSocketChannel.cpp
index 90f023c..5e14f97 100644
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -2292,7 +2292,7 @@ WebSocketChannel::ApplyForAdmission()
MOZ_ASSERT(!mCancelable);
- return pps->AsyncResolve(mURI,
+ return pps->AsyncResolve(mHttpChannel,
nsIProtocolProxyService::RESOLVE_PREFER_HTTPS_PROXY |
nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL,
this, getter_AddRefs(mCancelable));
@@ -2406,7 +2406,7 @@ WebSocketChannel::OnLookupComplete(nsICancelable *aRequest,
// nsIProtocolProxyCallback
NS_IMETHODIMP
-WebSocketChannel::OnProxyAvailable(nsICancelable *aRequest, nsIURI *aURI,
+WebSocketChannel::OnProxyAvailable(nsICancelable *aRequest, nsIChannel *aChannel,
nsIProxyInfo *pi, nsresult status)
{
if (mStopped) {
1
0
[tor-browser/tor-browser-31.2.0esr-4.5-1] Revert "fixup! Bug #5926: Allow customization of content JS locale."
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit e007a57d358f1165feb5f8506b4efe5be46224cb
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Thu Oct 30 13:31:11 2014 -0700
Revert "fixup! Bug #5926: Allow customization of content JS locale."
This reverts commit eb0ccdb7ffc70ffa4b4a60100606261882d68129.
I missed that the JS engine was managing its own copy of the returned string.
We do need to strdup it.
---
xpcom/build/nsXPComInit.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/xpcom/build/nsXPComInit.cpp b/xpcom/build/nsXPComInit.cpp
index 62f31bf..979e10b 100644
--- a/xpcom/build/nsXPComInit.cpp
+++ b/xpcom/build/nsXPComInit.cpp
@@ -493,7 +493,7 @@ void StartWatchingDefaultLocalePref() {
// Store the default JavaScript locale.
JSRuntime* rt = GetRuntime();
if (rt) {
- sJSLocale = JS_GetDefaultLocale(rt);
+ sJSLocale = strdup(JS_GetDefaultLocale(rt));
}
// Now keep the locale updated with the current pref value.
mozilla::Preferences::RegisterCallbackAndCall(DefaultLocaleChangedCallback, DEFAULT_LOCALE_PREF);
1
0
[tor-browser-bundle/master] Merge remote-tracking branch 'origin/master'
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit ab8da1c4a840f30f37873132258edc3f9711554b
Merge: 912a830 9f0cacb
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Thu Oct 30 13:47:37 2014 -0700
Merge remote-tracking branch 'origin/master'
gitian/versions.alpha | 3 +++
1 file changed, 3 insertions(+)
1
0
[tor-browser-bundle/master] Merge remote-tracking branch 'tjr/tjr-64bit'
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit 912a8305b26ce0b1cbc80c4014b4de3ada898991
Merge: af7bd8e f1f4a2a
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Wed Oct 29 15:14:09 2014 -0700
Merge remote-tracking branch 'tjr/tjr-64bit'
Conflicts:
gitian/descriptors/mac/gitian-pluggable-transports.yml
Bundle-Data/mac-tor.sh | 1 -
gitian/descriptors/mac/gitian-bundle.yml | 9 +++-----
gitian/descriptors/mac/gitian-firefox.yml | 3 ---
.../mac/gitian-pluggable-transports.yml | 16 ++++++-------
gitian/descriptors/mac/gitian-tor.yml | 16 ++++++-------
gitian/descriptors/mac/gitian-utils.yml | 16 +++++++------
gitian/mkbundle-mac.sh | 24 ++++++++++----------
7 files changed, 40 insertions(+), 45 deletions(-)
diff --cc gitian/descriptors/mac/gitian-pluggable-transports.yml
index 4c25f07,17aef86..6201230
--- a/gitian/descriptors/mac/gitian-pluggable-transports.yml
+++ b/gitian/descriptors/mac/gitian-pluggable-transports.yml
@@@ -48,10 -42,8 +48,10 @@@ files
- "apple-uni-sdk-10.6_20110407-0.flosoft1_i386.deb"
- "multiarch-darwin11-cctools127.2-gcc42-5666.3-llvmgcc42-2336.1-Linux-120724.tar.xz"
- "dzip.sh"
- - "gmp-mac32-utils.zip"
- - "openssl-mac32-utils.zip"
+- "go.crypto.tar.bz2"
+- "go.net.tar.bz2"
+ - "gmp-mac64-utils.zip"
+ - "openssl-mac64-utils.zip"
script: |
INSTDIR="$HOME/install"
TBDIR="$INSTDIR/TorBrowserBundle.app/TorBrowser"
@@@ -253,53 -245,7 +253,53 @@@
cp -a README doc/*.1 $TBDIR/Docs/meek
cd ..
+ # Building go ed25519
+ cd ed25519
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/github.com/agl/"
+ ln -sf "$PWD" "$GOPATH/src/github.com/agl/ed25519"
+ go install github.com/agl/ed25519/extra25519
+ cd ..
+
+ # Building go siphash
+ cd siphash
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/github.com/dchest/"
+ ln -sf "$PWD" "$GOPATH/src/github.com/dchest/siphash"
+ go install github.com/dchest/siphash
+ cd ..
+
+ # Building go.crypto
+ tar xjf go.crypto.tar.bz2
+ cd go.crypto
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/code.google.com/p/"
+ ln -sf "$PWD" "$GOPATH/src/code.google.com/p/go.crypto"
+ go install code.google.com/p/go.crypto/curve25519
+ go install code.google.com/p/go.crypto/hkdf
+ go install code.google.com/p/go.crypto/nacl/secretbox
+ cd ..
+
+ # Building go.net
+ tar xjf go.net.tar.bz2
+ cd go.net
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/code.google.com/p/"
+ ln -sf "$PWD" "$GOPATH/src/code.google.com/p/go.net"
+ go install code.google.com/p/go.net/proxy
+ cd ..
+
+ # Building obfs4proxy
+ cd obfs4
+ find -type f | xargs touch --date="$REFERENCE_DATETIME"
+ mkdir -p "$GOPATH/src/git.torproject.org/pluggable-transports"
+ ln -sf "$PWD" "$GOPATH/src/git.torproject.org/pluggable-transports/obfs4.git"
+ cd obfs4proxy
+ go build -ldflags '-s'
+ cp -a obfs4proxy $PTDIR
+ cd ../..
+
# Grabbing the result
cd $INSTDIR
- ~/build/dzip.sh pluggable-transports-mac$GBUILD_BITS-gbuilt.zip TorBrowserBundle.app
- cp pluggable-transports-mac$GBUILD_BITS-gbuilt.zip $OUTDIR/
+ ~/build/dzip.sh pluggable-transports-mac64-gbuilt.zip TorBrowserBundle.app
+ cp pluggable-transports-mac64-gbuilt.zip $OUTDIR/
1
0
[tor-browser-bundle/master] 64 bit build on Mac for all components. Tor-Browser requires an additional patch, and versions.alpa was not updated to point at the correct tag
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit f1f4a2a85da44820e148c47486363befc1a4bb16
Author: Tom Ritter <tom(a)ritter.vg>
Date: Tue Sep 16 21:46:00 2014 -0500
64 bit build on Mac for all components. Tor-Browser requires an additional patch, and versions.alpa was not updated to point at the correct tag
---
Bundle-Data/mac-tor.sh | 1 -
gitian/descriptors/mac/gitian-bundle.yml | 9 +++-----
gitian/descriptors/mac/gitian-firefox.yml | 3 ---
.../mac/gitian-pluggable-transports.yml | 16 ++++++-------
gitian/descriptors/mac/gitian-tor.yml | 16 ++++++-------
gitian/descriptors/mac/gitian-utils.yml | 16 +++++++------
gitian/mkbundle-mac.sh | 24 ++++++++++----------
7 files changed, 40 insertions(+), 45 deletions(-)
diff --git a/Bundle-Data/mac-tor.sh b/Bundle-Data/mac-tor.sh
index 9a22096..03d6f9d 100755
--- a/Bundle-Data/mac-tor.sh
+++ b/Bundle-Data/mac-tor.sh
@@ -1,7 +1,6 @@
#!/bin/sh
# Compiled Python modules require a compatible Python, which means 32-bit 2.6.
export VERSIONER_PYTHON_VERSION=2.6
-export VERSIONER_PYTHON_PREFER_32_BIT=yes
export DYLD_LIBRARY_PATH=.:$DYLD_LIBRARY_PATH
# Set the current working directory to the directory containing this executable,
# so that pluggable transport executables can be given with relative paths. This
diff --git a/gitian/descriptors/mac/gitian-bundle.yml b/gitian/descriptors/mac/gitian-bundle.yml
index 82b6595..1cf75e9 100644
--- a/gitian/descriptors/mac/gitian-bundle.yml
+++ b/gitian/descriptors/mac/gitian-bundle.yml
@@ -30,9 +30,9 @@ remotes:
"dir": "meek"
files:
# TODO: Can we use an env for this file+version??
-- "tor-browser-mac32-gbuilt.zip"
-- "tor-mac32-gbuilt.zip"
-- "pluggable-transports-mac32-gbuilt.zip"
+- "tor-browser-mac64-gbuilt.zip"
+- "tor-mac64-gbuilt.zip"
+- "pluggable-transports-mac64-gbuilt.zip"
- "torrc-defaults-appendix-mac"
- "bridge_prefs.js"
- "meek-http-helper-user.js"
@@ -75,9 +75,6 @@ script: |
unzip -d ~/build ~/build/mar-tools-mac$GBUILD_BITS.zip
MARTOOLS=~/build/mar-tools
#
- # XXX: Find a better way to tell that we are having a 32bit build
- GBUILD_BITS=32
- #
mkdir -p $OUTDIR/
mkdir -p $TORBROWSER_NAME.app/TorBrowser/Data/Browser/profile.default/extensions/https-everywhere(a)eff.org
mkdir -p $TORBROWSER_NAME.app/TorBrowser/Data/Browser/profile.meek-http-helper/extensions
diff --git a/gitian/descriptors/mac/gitian-firefox.yml b/gitian/descriptors/mac/gitian-firefox.yml
index fc36472..9126f03 100644
--- a/gitian/descriptors/mac/gitian-firefox.yml
+++ b/gitian/descriptors/mac/gitian-firefox.yml
@@ -95,9 +95,6 @@ script: |
zip -r mar-tools-mac${GBUILD_BITS}.zip mar-tools
cp -p mar-tools-mac${GBUILD_BITS}.zip $OUTDIR/
#
- # XXX: Find a better way to tell that we are having a 32bit build
- GBUILD_BITS=32
- #
cd $INSTDIR
# Adjust the Info.plist file
INFO_PLIST=TorBrowser.app/Contents/Info.plist
diff --git a/gitian/descriptors/mac/gitian-pluggable-transports.yml b/gitian/descriptors/mac/gitian-pluggable-transports.yml
index 33df49f..17aef86 100644
--- a/gitian/descriptors/mac/gitian-pluggable-transports.yml
+++ b/gitian/descriptors/mac/gitian-pluggable-transports.yml
@@ -42,8 +42,8 @@ files:
- "apple-uni-sdk-10.6_20110407-0.flosoft1_i386.deb"
- "multiarch-darwin11-cctools127.2-gcc42-5666.3-llvmgcc42-2336.1-Linux-120724.tar.xz"
- "dzip.sh"
-- "gmp-mac32-utils.zip"
-- "openssl-mac32-utils.zip"
+- "gmp-mac64-utils.zip"
+- "openssl-mac64-utils.zip"
script: |
INSTDIR="$HOME/install"
TBDIR="$INSTDIR/TorBrowserBundle.app/TorBrowser"
@@ -61,8 +61,8 @@ script: |
sudo dpkg -i *.deb
tar xaf multiarch-darwin*tar.xz
export PATH="$PATH:$HOME/build/apple-osx/bin/"
- unzip -d $INSTDIR gmp-mac32-utils.zip
- unzip -d $INSTDIR openssl-mac32-utils.zip
+ unzip -d $INSTDIR gmp-mac64-utils.zip
+ unzip -d $INSTDIR openssl-mac64-utils.zip
cp $INSTDIR/gmp/lib/*dylib* $TBDIR/Tor/
#
@@ -72,8 +72,8 @@ script: |
# http://bugs.python.org/issue9437
export LDSHARED="$CC -pthread -shared"
# XXX Clean up these flags?
- export CFLAGS="-I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -F/usr/lib/apple/SDKs/MacOSX10.6.sdk/System/Library/Frameworks -mmacosx-version-min=10.5 -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/i686-apple-darwin10/4.2.1 -I$INSTDIR/gmp/include -L$INSTDIR/gmp/lib"
- export CXXFLAGS="-I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -F/usr/lib/apple/SDKs/MacOSX10.6.sdk/System/Library/Frameworks -mmacosx-version-min=10.5 -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/i686-apple-darwin10/4.2.1 -I$INSTDIR/gmp/include -L$INSTDIR/gmp/lib"
+ export CFLAGS="-m64 -I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -F/usr/lib/apple/SDKs/MacOSX10.6.sdk/System/Library/Frameworks -mmacosx-version-min=10.5 -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/i686-apple-darwin10/4.2.1 -I$INSTDIR/gmp/include -L$INSTDIR/gmp/lib"
+ export CXXFLAGS="-m64 -I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -F/usr/lib/apple/SDKs/MacOSX10.6.sdk/System/Library/Frameworks -mmacosx-version-min=10.5 -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/i686-apple-darwin10/4.2.1 -I$INSTDIR/gmp/include -L$INSTDIR/gmp/lib"
export LDFLAGS="-L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -F/usr/lib/apple/SDKs/MacOSX10.6.sdk/System/Library/Frameworks -mmacosx-version-min=10.5"
# Building go
@@ -247,5 +247,5 @@ script: |
# Grabbing the result
cd $INSTDIR
- ~/build/dzip.sh pluggable-transports-mac$GBUILD_BITS-gbuilt.zip TorBrowserBundle.app
- cp pluggable-transports-mac$GBUILD_BITS-gbuilt.zip $OUTDIR/
+ ~/build/dzip.sh pluggable-transports-mac64-gbuilt.zip TorBrowserBundle.app
+ cp pluggable-transports-mac64-gbuilt.zip $OUTDIR/
diff --git a/gitian/descriptors/mac/gitian-tor.yml b/gitian/descriptors/mac/gitian-tor.yml
index 6022c0b..555440f 100644
--- a/gitian/descriptors/mac/gitian-tor.yml
+++ b/gitian/descriptors/mac/gitian-tor.yml
@@ -26,8 +26,8 @@ files:
- "apple-uni-sdk-10.6_20110407-0.flosoft1_i386.deb"
- "multiarch-darwin11-cctools127.2-gcc42-5666.3-llvmgcc42-2336.1-Linux-120724.tar.xz"
- "dzip.sh"
-- "openssl-mac32-utils.zip"
-- "libevent-mac32-utils.zip"
+- "openssl-mac64-utils.zip"
+- "libevent-mac64-utils.zip"
script: |
INSTDIR="$HOME/install"
TBDIR="$INSTDIR/TorBrowserBundle.app/TorBrowser"
@@ -46,15 +46,15 @@ script: |
sudo dpkg -i *.deb
tar xaf multiarch-darwin*tar.xz
export PATH="$PATH:$HOME/build/apple-osx/bin/"
- unzip -d $INSTDIR openssl-mac32-utils.zip
- unzip -d $INSTDIR libevent-mac32-utils.zip
+ unzip -d $INSTDIR openssl-mac64-utils.zip
+ unzip -d $INSTDIR libevent-mac64-utils.zip
cp $INSTDIR/libevent/lib/libevent-*.dylib $TBDIR/Tor/
LIBEVENT_FILE=`basename $INSTDIR/libevent/lib/libevent-*.dylib`
# Building tor
# XXX Clean up these flags?
- export CFLAGS="-I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
- export LDFLAGS="-L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
+ export CFLAGS="-m64 -I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
+ export LDFLAGS="-m64 -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
cd tor
git update-index --refresh -q
export GIT_COMMITTER_NAME="nobody"
@@ -94,5 +94,5 @@ script: |
# Grabbing the result
cd $INSTDIR
- ~/build/dzip.sh tor-mac32-gbuilt.zip TorBrowserBundle.app
- cp tor-mac32-gbuilt.zip $OUTDIR/
+ ~/build/dzip.sh tor-mac64-gbuilt.zip TorBrowserBundle.app
+ cp tor-mac64-gbuilt.zip $OUTDIR/
diff --git a/gitian/descriptors/mac/gitian-utils.yml b/gitian/descriptors/mac/gitian-utils.yml
index 785d88c..f96b5ec 100644
--- a/gitian/descriptors/mac/gitian-utils.yml
+++ b/gitian/descriptors/mac/gitian-utils.yml
@@ -34,10 +34,12 @@ script: |
export PATH="$PATH:$HOME/build/apple-osx/bin/"
# For OpenSSL
ln -s ~/build/apple-osx/bin/apple-osx-gcc ~/build/apple-osx/bin/i686-apple-darwin11-cc
+ #For gmp, need to trick it so it knows we're doing a 64 bit build
+ for i in ~/build/apple-osx/bin/i686-apple-darwin11-*; do j=`echo $i | sed 's/i686/x86_64/'`; ln -s $i $j; done;
# XXX Clean up these flags?
- export CFLAGS="-I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
- export CXXFLAGS="-I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/i686-apple-darwin10/4.2.1 -mmacosx-version-min=10.5"
+ export CFLAGS="-m64 -I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
+ export CXXFLAGS="-m64 -I/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/include/ -I/usr/lib/gcc/i686-apple-darwin10/4.2.1/include/ -I. -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/i686-apple-darwin10/4.2.1 -mmacosx-version-min=10.5"
export LDFLAGS="-L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/ -L/usr/lib/apple/SDKs/MacOSX10.6.sdk/usr/lib/system/ -mmacosx-version-min=10.5"
# Building Libevent
@@ -54,7 +56,7 @@ script: |
cd openssl-*
find -type f | xargs touch --date="$REFERENCE_DATETIME"
# TODO: Add enable-ec_nistp_64_gcc_128 for 64bit OS X.
- ./Configure --cross-compile-prefix=i686-apple-darwin11- $CFLAGS darwin-i386-cc --prefix=$INSTDIR/openssl
+ ./Configure --cross-compile-prefix=i686-apple-darwin11- $CFLAGS darwin64-x86_64-cc --prefix=$INSTDIR/openssl enable-ec_nistp_64_gcc_128
# Using $MAKEOPTS breaks the build. Might be the issue mentioned on
# http://cblfs.cross-lfs.org/index.php/OpenSSL.
make
@@ -65,15 +67,15 @@ script: |
tar xjf gmp.tar.bz2
cd gmp-*
find -type f | xargs touch --date="$REFERENCE_DATETIME"
- ./configure --host=i686-apple-darwin11 --prefix=$INSTDIR/gmp --disable-static --enable-shared --enable-cxx
+ ./configure --host=x86_64-apple-darwin11 --prefix=$INSTDIR/gmp --disable-static --enable-shared --enable-cxx
make
make install
cd ..
# Grabbing the results
cd $INSTDIR
- ~/build/dzip.sh openssl-$OPENSSL_VER-mac32-utils.zip openssl
- ~/build/dzip.sh libevent-${LIBEVENT_TAG#release-}-mac32-utils.zip libevent
- ~/build/dzip.sh gmp-$GMP_VER-mac32-utils.zip gmp
+ ~/build/dzip.sh openssl-$OPENSSL_VER-mac64-utils.zip openssl
+ ~/build/dzip.sh libevent-${LIBEVENT_TAG#release-}-mac64-utils.zip libevent
+ ~/build/dzip.sh gmp-$GMP_VER-mac64-utils.zip gmp
cp *utils.zip $OUTDIR/
diff --git a/gitian/mkbundle-mac.sh b/gitian/mkbundle-mac.sh
index 9c5d99b..c8830af 100755
--- a/gitian/mkbundle-mac.sh
+++ b/gitian/mkbundle-mac.sh
@@ -103,9 +103,9 @@ fi
cd $GITIAN_DIR
-if [ ! -f inputs/openssl-$OPENSSL_VER-mac32-utils.zip -o \
- ! -f inputs/libevent-${LIBEVENT_TAG_ORIG#release-}-mac32-utils.zip -o \
- ! -f inputs/gmp-$GMP_VER-mac32-utils.zip ];
+if [ ! -f inputs/openssl-$OPENSSL_VER-mac64-utils.zip -o \
+ ! -f inputs/libevent-${LIBEVENT_TAG_ORIG#release-}-mac64-utils.zip -o \
+ ! -f inputs/gmp-$GMP_VER-mac64-utils.zip ];
then
echo
echo "****** Starting Utilities Component of Mac Bundle (1/5 for Mac) ******"
@@ -119,9 +119,9 @@ then
cd inputs
cp -a ../build/out/*-utils.zip .
- ln -sf openssl-$OPENSSL_VER-mac32-utils.zip openssl-mac32-utils.zip
- ln -sf libevent-${LIBEVENT_TAG_ORIG#release-}-mac32-utils.zip libevent-mac32-utils.zip
- ln -sf gmp-$GMP_VER-mac32-utils.zip gmp-mac32-utils.zip
+ ln -sf openssl-$OPENSSL_VER-mac64-utils.zip openssl-mac64-utils.zip
+ ln -sf libevent-${LIBEVENT_TAG_ORIG#release-}-mac64-utils.zip libevent-mac64-utils.zip
+ ln -sf gmp-$GMP_VER-mac64-utils.zip gmp-mac64-utils.zip
cd ..
#cp -a result/utils-mac-res.yml inputs/
else
@@ -132,13 +132,13 @@ else
# We might have built the utilities in the past but maybe the links are
# pointing to the wrong version. Refresh them.
cd inputs
- ln -sf openssl-$OPENSSL_VER-mac32-utils.zip openssl-mac32-utils.zip
- ln -sf libevent-${LIBEVENT_TAG_ORIG#release-}-mac32-utils.zip libevent-mac32-utils.zip
- ln -sf gmp-$GMP_VER-mac32-utils.zip gmp-mac32-utils.zip
+ ln -sf openssl-$OPENSSL_VER-mac64-utils.zip openssl-mac64-utils.zip
+ ln -sf libevent-${LIBEVENT_TAG_ORIG#release-}-mac64-utils.zip libevent-mac64-utils.zip
+ ln -sf gmp-$GMP_VER-mac64-utils.zip gmp-mac64-utils.zip
cd ..
fi
-if [ ! -f inputs/tor-mac32-gbuilt.zip ];
+if [ ! -f inputs/tor-mac64-gbuilt.zip ];
then
echo
echo "****** Starting Tor Component of Mac Bundle (2/5 for Mac) ******"
@@ -159,7 +159,7 @@ else
echo
fi
-if [ ! -f inputs/tor-browser-mac32-gbuilt.zip ];
+if [ ! -f inputs/tor-browser-mac64-gbuilt.zip ];
then
echo
echo "****** Starting TorBrowser Component of Mac Bundle (3/5 for Mac) ******"
@@ -181,7 +181,7 @@ else
echo
fi
-if [ ! -f inputs/pluggable-transports-mac32-gbuilt.zip ];
+if [ ! -f inputs/pluggable-transports-mac64-gbuilt.zip ];
then
echo
echo "****** Starting Pluggable Transports Component of Mac Bundle (4/5 for Mac) ******"
1
0
[tor-browser-bundle/master] Bump obfs4 related tags/commits for 4.5-alpha.
by gk@torproject.org 30 Oct '14
by gk@torproject.org 30 Oct '14
30 Oct '14
commit 9f0cacb1cf6a075e91e4da1a4f56d31cd30b33cf
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Oct 30 13:56:04 2014 +0000
Bump obfs4 related tags/commits for 4.5-alpha.
---
gitian/versions.alpha | 3 +++
1 file changed, 3 insertions(+)
diff --git a/gitian/versions.alpha b/gitian/versions.alpha
index 6c49137..c4b65c3 100755
--- a/gitian/versions.alpha
+++ b/gitian/versions.alpha
@@ -27,6 +27,9 @@ TXSOCKSX_TAG=216eb0894a1755872f4789f9458aa6cf543b8433 # unsigned habnabit/1.13.0
GOPTLIB_TAG=0.2
MEEK_TAG=0.11
FAKETIME_TAG=70aa6b394d9341522dffe8a5a5cf5929e82cc6b9 # unsigned v0.9.6
+GOED25519_TAG=c4161f4c7483313562781c61b9a20aba73daf9de
+GOSIPHASH_TAG=42ba037e748c9062a75e0924705c43b893edefcd
+OBFS4_TAG=0.0.3
GITIAN_TAG=tor-browser-builder-3.x-7
1
0