tor-commits
Threads by month
- ----- 2025 -----
- 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
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
October 2014
- 26 participants
- 1551 discussions

[torbutton/master] Bug 9387: Version 0.2 of the Security Slider.
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit cda1d6cd71a5c5b84dfd45bcf042b5ada8ee58b4
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu Oct 30 22:54:32 2014 +0000
Bug 9387: Version 0.2 of the Security Slider.
Version 0.2 contains the slider and the option to choose a mode which
results in preferences enabled/disabled depending on the respective
security level chosen. The UI is in Torbutton's preferences dialog only
for now. If the user manipluates preferences governed by the slider the
custom checkbox is checked and unhidden indicating that the user is
currently in a non-standard user group.
Missing pieces:
-tooltips/help buttons explaining the security levels
-preferences for disabling SVG and MathML (#12827 and #13548)
---
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(-)
diff --git a/src/chrome/content/preferences.js b/src/chrome/content/preferences.js
index 4c3c74d..20a6c9f 100644
--- a/src/chrome/content/preferences.js
+++ b/src/chrome/content/preferences.js
@@ -180,10 +180,21 @@ function torbutton_prefs_init(doc) {
doc.getElementById('torbutton_settingsMethod').selectedItem = doc.getElementById('torbutton_transparentTor');
}
+ // Privacy and security settings
doc.getElementById('torbutton_blockDisk').checked = o_torprefs.getBoolPref('block_disk');
doc.getElementById('torbutton_resistFingerprinting').checked = o_torprefs.getBoolPref('resist_fingerprinting');
doc.getElementById('torbutton_blockPlugins').checked = o_torprefs.getBoolPref('no_tor_plugins');
doc.getElementById('torbutton_restrictThirdParty').checked = o_torprefs.getBoolPref('restrict_thirdparty');
+ let sec_slider = doc.getElementById('torbutton_sec_slider');
+ let sec_custom = doc.getElementById('torbutton_sec_custom');
+ let custom_values = o_torprefs.getBoolPref('security_custom');
+ sec_slider.value = o_torprefs.getIntPref('security_slider');
+ sec_slider.disabled = custom_values;
+ // Setting |disabled| to |false| is not enough to have the element
+ // non-responding. We need to handle |movetoclick| as well.
+ sec_slider.setAttribute("movetoclick", !custom_values);
+ sec_custom.checked = custom_values;
+ sec_custom.collapsed = !custom_values;
torbutton_prefs_set_field_attributes(doc);
}
@@ -273,13 +284,22 @@ function torbutton_prefs_save(doc) {
}
}
+ // Privacy and Security Settings
o_torprefs.setBoolPref('block_disk', doc.getElementById('torbutton_blockDisk').checked);
o_torprefs.setBoolPref('resist_fingerprinting', doc.getElementById('torbutton_resistFingerprinting').checked);
o_torprefs.setBoolPref('no_tor_plugins', doc.getElementById('torbutton_blockPlugins').checked);
o_torprefs.setBoolPref('restrict_thirdparty', doc.getElementById('torbutton_restrictThirdParty').checked);
+ o_torprefs.setBoolPref('security_custom',
+ doc.getElementById('torbutton_sec_custom').checked);
+ o_torprefs.setIntPref('security_slider',
+ doc.getElementById('torbutton_sec_slider').value);
// if tor settings were initially active, update the active settings to reflect any changes
if (tor_enabled) torbutton_activate_tor_settings();
+ // If we have non-custom Security Slider settings update them now.
+ if (!o_torprefs.getBoolPref('security_custom')) {
+ win.torbutton_update_security_slider();
+ }
}
function torbutton_prefs_test_settings() {
@@ -413,6 +433,11 @@ function torbutton_prefs_reset_defaults() {
}
}
+ // Resetting the Security Slider preferences
+ o_torprefs.setBoolPref('security_custom', false);
+ o_torprefs.setIntPref('security_slider', 1);
+ chrome.torbutton_update_security_slider();
+
torbutton_log(4, "Preferences reset to defaults");
torbutton_prefs_init(window.document);
@@ -421,3 +446,15 @@ function torbutton_prefs_reset_defaults() {
.getService(Components.interfaces.nsIPrefService);
prefService.savePrefFile(null);
}
+
+function torbutton_toggle_slider(doc) {
+ let slider = doc.getElementById("torbutton_sec_slider");
+ if (doc.getElementById("torbutton_sec_custom").checked) {
+ slider.disabled = true;
+ slider.setAttribute("movetoclick", false);
+ } else {
+ slider.disabled = false;
+ slider.setAttribute("movetoclick", true);
+ }
+}
+
diff --git a/src/chrome/content/preferences.xul b/src/chrome/content/preferences.xul
index 5198565..7c5633b 100644
--- a/src/chrome/content/preferences.xul
+++ b/src/chrome/content/preferences.xul
@@ -19,7 +19,7 @@
<tabbox>
<tabs>
<tab label="&torbutton.prefs.tor_settings;"/>
- <tab label="&torbutton.prefs.sec_settings;"/>
+ <tab label="&torbutton.prefs.privacy_security_settings;"/>
</tabs>
<tabpanels>
<tabpanel>
@@ -140,16 +140,56 @@
</vbox>
</tabpanel>
<tabpanel>
- <vbox>
- <checkbox id="torbutton_blockDisk"
- label="&torbutton.prefs.block_disk;"/>
- <checkbox id="torbutton_blockPlugins"
- label="&torbutton.prefs.block_plugins;"/>
- <checkbox id="torbutton_restrictThirdParty"
- label="&torbutton.prefs.restrict_thirdparty;"/>
- <checkbox id="torbutton_resistFingerprinting"
- label="&torbutton.prefs.resist_fingerprinting;"/>
- </vbox>
+ <vbox>
+ <groupbox>
+ <caption label="&torbutton.prefs.priv_caption;"/>
+ <checkbox id="torbutton_blockDisk"
+ label="&torbutton.prefs.block_disk;"/>
+ <checkbox id="torbutton_blockPlugins"
+ label="&torbutton.prefs.block_plugins;"/>
+ <checkbox id="torbutton_restrictThirdParty"
+ label="&torbutton.prefs.restrict_thirdparty;"/>
+ <checkbox id="torbutton_resistFingerprinting"
+ label="&torbutton.prefs.resist_fingerprinting;"/>
+ </groupbox>
+ <spacer flex="1"/>
+ <groupbox>
+ <caption label="&torbutton.prefs.sec_caption;"/>
+ <hbox>
+ <vbox>
+ <scale id="torbutton_sec_slider" height="200" min="1" max="4"
+ movetoclick="true" orient="vertical"/>
+ </vbox>
+ <vbox height="200">
+ <hbox flex="1" align="center">
+ <description id="torbutton_sec_low">
+ &torbutton.prefs.sec_low;
+ </description>
+ </hbox>
+ <hbox flex="1" align="center">
+ <description id="torbutton_sec_med_low">
+ &torbutton.prefs.sec_med_low;
+ </description>
+ </hbox>
+ <hbox flex="1" align="center">
+ <description id="torbutton_sec_med_high">
+ &torbutton.prefs.sec_med_high;
+ </description>
+ </hbox>
+ <hbox flex="1" align="center">
+ <description id="torbutton_sec_high">
+ &torbutton.prefs.sec_high;
+ </description>
+ </hbox>
+ </vbox>
+ </hbox>
+ <hbox>
+ <checkbox id="torbutton_sec_custom" flex="1"
+ oncommand="torbutton_toggle_slider(document);"
+ label="&torbutton.prefs.sec_custom;"/>
+ </hbox>
+ </groupbox>
+ </vbox>
</tabpanel>
</tabpanels>
diff --git a/src/chrome/content/torbutton.js b/src/chrome/content/torbutton.js
index 44020ec..6995197 100644
--- a/src/chrome/content/torbutton.js
+++ b/src/chrome/content/torbutton.js
@@ -52,6 +52,8 @@ var m_tb_orig_BrowserOnAboutPageLoad = null;
var m_tb_domWindowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
+var m_tb_sliderUpdate = false;
+
// Bug 1506 P1: This object is only for updating the UI for toggling and style
var torbutton_window_pref_observer =
{
@@ -118,6 +120,12 @@ var torbutton_unique_pref_observer =
this._branch.addObserver("network.proxy", this, false);
this._branch.addObserver("network.cookie", this, false);
this._branch.addObserver("browser.privatebrowsing.autostart", this, false);
+ this._branch.addObserver("javascript", this, false);
+ this._branch.addObserver("gfx", this, false);
+ this._branch.addObserver("noscript", this, false);
+ this._branch.addObserver("media", this, false);
+ this._branch.addObserver("capability.policy.maonoscript.sites", this,
+ false);
// We observe xpcom-category-entry-added for plugins w/ Gecko-Content-Viewers
var observerService = Cc["@mozilla.org/observer-service;1"].
@@ -132,6 +140,11 @@ var torbutton_unique_pref_observer =
this._branch.removeObserver("network.proxy", this);
this._branch.removeObserver("network.cookie", this);
this._branch.removeObserver("browser.privatebrowsing.autostart", this);
+ this._branch.removeObserver("javascript", this);
+ this._branch.removeObserver("gfx", this);
+ this._branch.removeObserver("noscript", this);
+ this._branch.removeObserver("media", this);
+ this._branch.removeObserver("capability.policy.maonoscript.sites", this);
var observerService = Cc["@mozilla.org/observer-service;1"].
getService(Ci.nsIObserverService);
@@ -218,6 +231,32 @@ var torbutton_unique_pref_observer =
case "extensions.torbutton.restrict_thirdparty":
torbutton_update_thirdparty_prefs();
break;
+ case "gfx.font_rendering.opentype_svg.enabled":
+ case "javascript.options.ion.content":
+ case "javascript.options.typeinference":
+ case "javascript.options.asmjs":
+ case "noscript.forbidMedia":
+ case "media.webaudio.enabled":
+ case "javascript.options.baselinejit.content":
+ case "noscript.forbidFonts":
+ case "gfx.font_rendering.graphite.enabled":
+ case "noscript.globalHttpsWhitelist":
+ case "noscript.global":
+ case "media.ogg.enabled":
+ case "media.opus.enabled":
+ case "media.wave.enabled":
+ case "media.apple.mp3.enabled":
+ case "capability.policy.maonoscript.sites":
+ if (!m_tb_sliderUpdate) {
+ // Do we already have custom settings?
+ let customSlider = m_tb_prefs.
+ getBoolPref("extensions.torbutton.security_custom");
+ if (!customSlider) {
+ m_tb_prefs.
+ setBoolPref("extensions.torbutton.security_custom", true);
+ }
+ }
+ break;
}
}
}
@@ -513,6 +552,8 @@ function torbutton_init() {
// initialize preferences before we start our prefs observer
torbutton_init_prefs();
+ // set some important security prefs according to the chosen security level
+ torbutton_update_security_slider();
// set panel style from preferences
torbutton_set_panel_style();
@@ -2092,6 +2133,142 @@ function torbutton_update_thirdparty_prefs() {
prefService.savePrefFile(null);
}
+var torbutton_sec_l_bool_prefs = {
+ "gfx.font_rendering.opentype_svg.enabled" : false,
+};
+
+var torbutton_sec_ml_bool_prefs = {
+ "javascript.options.ion.content" : false,
+ "javascript.options.typeinference" : false,
+ "javascript.options.asmjs" : false,
+ "noscript.forbidMedia" : true,
+ "media.webaudio.enabled" : false,
+ // XXX: pref for disabling MathML is missing
+};
+
+var torbutton_sec_mh_bool_prefs = {
+ "javascript.options.baselinejit.content" : false,
+ "noscript.globalHttpsWhitelist" : true,
+ // XXX: pref for disableing SVG is missing
+};
+
+var torbutton_sec_h_bool_prefs = {
+ "noscript.forbidFonts" : true,
+ "noscript.global" : false,
+ "media.ogg.enabled" : false,
+ "media.opus.enabled" : false,
+ "media.wave.enabled" : false,
+ "media.apple.mp3.enabled" : false
+};
+
+function torbutton_update_security_slider() {
+ // Avoid checking the custom settings checkbox.
+ m_tb_sliderUpdate = true;
+ let mode = m_tb_prefs.getIntPref("extensions.torbutton.security_slider");
+ let capValue = m_tb_prefs.getCharPref("capability.policy.maonoscript.sites");
+ switch (mode) {
+ case 1:
+ for (p in torbutton_sec_l_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, torbutton_sec_l_bool_prefs[p]);
+ }
+ for (p in torbutton_sec_ml_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, !torbutton_sec_ml_bool_prefs[p])
+ }
+ for (p in torbutton_sec_mh_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, !torbutton_sec_mh_bool_prefs[p])
+ }
+ for (p in torbutton_sec_h_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, !torbutton_sec_h_bool_prefs[p])
+ }
+ // XXX: Adding and removing "https:" is needed due to a bug in Noscript.
+ if (capValue.indexOf(" https:") >= 0) {
+ m_tb_prefs.setCharPref("capability.policy.maonoscript.sites",
+ capValue.replace(" https:", ""));
+ }
+ if (m_tb_prefs.getCharPref("general.useragent.locale") !== "ko" ||
+ m_tb_prefs.getCharPref("general.useragent.locale") !== "vi" ||
+ m_tb_prefs.getCharPref("general.useragent.locale") !== "zh-CN") {
+ m_tb_prefs.setBoolPref("gfx.font_rendering.graphite.enabled", false);
+ } else {
+ m_tb_prefs.setBoolPref("gfx.font_rendering.graphite.enabled", true);
+ }
+ break;
+ case 2:
+ for (p in torbutton_sec_l_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, torbutton_sec_l_bool_prefs[p]);
+ }
+ for (p in torbutton_sec_ml_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, torbutton_sec_ml_bool_prefs[p])
+ }
+ for (p in torbutton_sec_mh_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, !torbutton_sec_mh_bool_prefs[p])
+ }
+ for (p in torbutton_sec_h_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, !torbutton_sec_h_bool_prefs[p])
+ }
+ // XXX: Adding and removing "https:" is needed due to a bug in Noscript.
+ if (capValue.indexOf(" https:") >= 0) {
+ m_tb_prefs.setCharPref("capability.policy.maonoscript.sites",
+ capValue.replace(" https:", ""));
+ }
+ if (m_tb_prefs.getCharPref("general.useragent.locale") !== "ko" ||
+ m_tb_prefs.getCharPref("general.useragent.locale") !== "vi" ||
+ m_tb_prefs.getCharPref("general.useragent.locale") !== "zh-CN") {
+ m_tb_prefs.setBoolPref("gfx.font_rendering.graphite.enabled", false);
+ } else {
+ m_tb_prefs.setBoolPref("gfx.font_rendering.graphite.enabled", true);
+ }
+ break;
+ case 3:
+ for (p in torbutton_sec_l_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, torbutton_sec_l_bool_prefs[p]);
+ }
+ for (p in torbutton_sec_ml_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, torbutton_sec_ml_bool_prefs[p])
+ }
+ for (p in torbutton_sec_mh_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, torbutton_sec_mh_bool_prefs[p])
+ }
+ for (p in torbutton_sec_h_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, !torbutton_sec_h_bool_prefs[p])
+ }
+ // XXX: Adding and removing "https:" is needed due to a bug in Noscript.
+ // missing.
+ if (capValue.indexOf(" https:") < 0) {
+ m_tb_prefs.setCharPref("capability.policy.maonoscript.sites", capValue +
+ " https:");
+ }
+ m_tb_prefs.setBoolPref("gfx.font_rendering.graphite.enabled", false);
+ break;
+ case 4:
+ for (p in torbutton_sec_l_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, torbutton_sec_l_bool_prefs[p]);
+ }
+ for (p in torbutton_sec_ml_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, torbutton_sec_ml_bool_prefs[p])
+ }
+ for (p in torbutton_sec_mh_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, torbutton_sec_mh_bool_prefs[p])
+ // noscript.globalHttpsWhitelist is special: We don't want it in this
+ // mode.
+ if (p == "noscript.globalHttpsWhitelist") {
+ m_tb_prefs.setBoolPref(p, !torbutton_sec_mh_bool_prefs[p])
+ }
+ }
+ for (p in torbutton_sec_h_bool_prefs) {
+ m_tb_prefs.setBoolPref(p, torbutton_sec_h_bool_prefs[p])
+ }
+ // XXX: Adding and removing "https:" is needed due to a bug in Noscript.
+ if (capValue.indexOf(" https:") >= 0) {
+ m_tb_prefs.setCharPref("capability.policy.maonoscript.sites",
+ capValue.replace(" https:", ""));
+ }
+ m_tb_prefs.setBoolPref("gfx.font_rendering.graphite.enabled", true);
+ break;
+ }
+ m_tb_sliderUpdate = false;
+}
+
// Bug 1506 P0: This code is a toggle-relic.
//
// It basically just enforces the three Torbutton prefs
diff --git a/src/chrome/locale/en/torbutton.dtd b/src/chrome/locale/en/torbutton.dtd
index 1457b20..283032b 100644
--- a/src/chrome/locale/en/torbutton.dtd
+++ b/src/chrome/locale/en/torbutton.dtd
@@ -44,7 +44,7 @@
<!ENTITY torbutton.context_menu.openTorWindow.key "d">
<!ENTITY torbutton.button.label "Torbutton">
<!ENTITY torbutton.button.tooltip "Click to initialize Torbutton">
-<!ENTITY torbutton.prefs.sec_settings "Security Settings">
+<!ENTITY torbutton.prefs.privacy_security_settings "Privacy and Security Settings">
<!ENTITY torbutton.prefs.block_thread "Block history reads during Tor (crucial)">
<!ENTITY torbutton.prefs.block_thwrite "Block history writes during Tor (recommended)">
<!ENTITY torbutton.prefs.block_nthread "Block history reads during Non-Tor (optional)">
@@ -144,7 +144,14 @@
<!ENTITY torbutton.prefs.engine5 "duckduckgo.com">
<!ENTITY torbutton.prefs.fix_google_srch "Strip platform and language off of Google Search Box queries">
<!ENTITY torbutton.prefs.transparentTor "Transparent Torification (Requires custom transproxy or Tor router)">
+<!ENTITY torbutton.prefs.priv_caption "Privacy Settings">
<!ENTITY torbutton.prefs.block_disk "Don't record browsing history or website data (enables Private Browsing Mode)">
<!ENTITY torbutton.prefs.restrict_thirdparty "Restrict third party cookies and other tracking data">
<!ENTITY torbutton.prefs.block_plugins "Disable browser plugins (such as Flash)">
<!ENTITY torbutton.prefs.resist_fingerprinting "Change details that distinguish you from other Tor Browser users">
+<!ENTITY torbutton.prefs.sec_caption "Security Level">
+<!ENTITY torbutton.prefs.sec_low "Low (default)">
+<!ENTITY torbutton.prefs.sec_med_low "Medium-Low">
+<!ENTITY torbutton.prefs.sec_med_high "Medium-High">
+<!ENTITY torbutton.prefs.sec_high "High">
+<!ENTITY torbutton.prefs.sec_custom "Custom Values">
diff --git a/src/defaults/preferences/preferences.js b/src/defaults/preferences/preferences.js
index af9838a..d527d7e 100644
--- a/src/defaults/preferences/preferences.js
+++ b/src/defaults/preferences/preferences.js
@@ -173,6 +173,9 @@ pref("extensions.torbutton(a)torproject.org.getAddons.cache.enabled", false);
pref("extensions.torbutton.block_disk", true);
pref("extensions.torbutton.resist_fingerprinting", true);
pref("extensions.torbutton.restrict_thirdparty", true);
+// Security Slider
+pref("extensions.torbutton.security_slider", 1);
+pref("extensions.torbutton.security_custom", false);
// Google Captcha prefs
// FIXME: NID cookie?
1
0

[tor/master] Teach format_changelog.py --blog about drupal <!--break-->
by nickm@torproject.org 30 Oct '14
by nickm@torproject.org 30 Oct '14
30 Oct '14
commit 96e3936fb7ab0a584357e42dad19ecaa0c0456a6
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu Oct 30 17:08:42 2014 -0400
Teach format_changelog.py --blog about drupal <!--break-->
---
scripts/maint/format_changelog.py | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/scripts/maint/format_changelog.py b/scripts/maint/format_changelog.py
index 35dc725..4f3c62d 100755
--- a/scripts/maint/format_changelog.py
+++ b/scripts/maint/format_changelog.py
@@ -238,7 +238,7 @@ def head_score(s):
return score
class ChangeLog(object):
- def __init__(self, wrapText=True, blogOrder=True):
+ def __init__(self, wrapText=True, blogOrder=True, drupalBreak=False):
self.prehead = []
self.mainhead = None
self.headtext = []
@@ -248,6 +248,7 @@ class ChangeLog(object):
self.lineno = 0
self.wrapText = wrapText
self.blogOrder = blogOrder
+ self.drupalBreak = drupalBreak
def addLine(self, tp, line):
self.lineno += 1
@@ -342,6 +343,9 @@ class ChangeLog(object):
def dumpEndOfChangelog(self):
print
+ def dumpDrupalBreak(self):
+ pass
+
def dumpItem(self, grafs):
self.dumpGraf(grafs[0],4,6)
for par in grafs[1:]:
@@ -377,6 +381,10 @@ class ChangeLog(object):
if self.blogOrder:
self.dumpMainhead(self.mainhead)
+ drupalBreakAfter = None
+ if self.drupalBreak and len(self.sections) > 4:
+ drupalBreakAfter = self.sections[1][2]
+
self.dumpStartOfSections()
for _,head,items in self.sections:
if not head.endswith(':'):
@@ -386,6 +394,8 @@ class ChangeLog(object):
for _,grafs in items:
self.dumpItem(grafs)
self.dumpEndOfSection()
+ if items is drupalBreakAfter:
+ self.dumpDrupalBreak()
self.dumpEndOfSections()
self.dumpEndOfChangelog()
@@ -431,6 +441,9 @@ class HTMLChangeLog(ChangeLog):
def dumpEndOfSections(self):
print "</ul>\n"
+ def dumpDrupalBreak(self):
+ print "\n<!--break-->\n\n"
+
def dumpItem(self, grafs):
grafs[0][0] = grafs[0][0].replace(" - ", "", 1).lstrip()
sys.stdout.write(" <li>")
@@ -465,6 +478,9 @@ op.add_option('-B', '--blog', action='store_true',
op.add_option('--inplace', action='store_true',
dest='inplace', default=False,
help="Alter the ChangeLog in place")
+op.add_option('--drupal-break', action='store_true',
+ dest='drupalBreak', default=False,
+ help='Insert a drupal-friendly <!--break--> as needed')
options,args = op.parse_args()
@@ -474,6 +490,7 @@ if options.blogFormat:
options.sort = False
options.wrapText = False
options.firstOnly = True
+ options.drupalBreak = True
if len(args) > 1:
op.error("Too many arguments")
@@ -496,7 +513,9 @@ if options.html:
else:
ChangeLogClass = ChangeLog
-CL = ChangeLogClass(wrapText=options.wrapText, blogOrder=options.blogOrder)
+CL = ChangeLogClass(wrapText=options.wrapText,
+ blogOrder=options.blogOrder,
+ drupalBreak=options.drupalBreak)
parser = head_parser
for line in sys.stdin:
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

[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

30 Oct '14
commit 0eb18866929837b8c04d2ff5b4cb464d70397463
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu Oct 30 16:54:10 2014 -0400
Twiddle the format_changelog.py option defaults.
---
scripts/maint/format_changelog.py | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/scripts/maint/format_changelog.py b/scripts/maint/format_changelog.py
index 686ebba..35dc725 100755
--- a/scripts/maint/format_changelog.py
+++ b/scripts/maint/format_changelog.py
@@ -449,19 +449,32 @@ op.add_option('-S', '--no-sort', action='store_false',
dest='sort', default=True,
help='Do not sort or collate sections')
op.add_option('-o', '--output', dest='output',
- default=None, metavar='FILE', help="write output to FILE")
+ default='-', metavar='FILE', help="write output to FILE")
op.add_option('-H', '--html', action='store_true',
dest='html', default=False,
help="generate an HTML fragment")
op.add_option('-1', '--first', action='store_true',
dest='firstOnly', default=False,
help="write only the first section")
-op.add_option('-b', '--blog-format', action='store_true',
+op.add_option('-b', '--blog-header', action='store_true',
dest='blogOrder', default=False,
help="Write the header in blog order")
+op.add_option('-B', '--blog', action='store_true',
+ dest='blogFormat', default=False,
+ help="Set all other options as appropriate for a blog post")
+op.add_option('--inplace', action='store_true',
+ dest='inplace', default=False,
+ help="Alter the ChangeLog in place")
options,args = op.parse_args()
+if options.blogFormat:
+ options.blogOrder = True
+ options.html = True
+ options.sort = False
+ options.wrapText = False
+ options.firstOnly = True
+
if len(args) > 1:
op.error("Too many arguments")
elif len(args) == 0:
@@ -469,7 +482,8 @@ elif len(args) == 0:
else:
fname = args[0]
-if options.output == None:
+if options.inplace:
+ assert options.output == '-'
options.output = fname
if fname != '-':
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] 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] 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] 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] 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