tbb-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
- 1 participants
- 18563 discussions

31 Oct '14
commit 978cac0e8d43caab6ddcfcb4a0b4634c375099ea
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Thu Oct 30 17:45:16 2014 -0700
Update version and changelog for 1.8.0.0.
---
src/CHANGELOG | 6 ++++++
src/install.rdf | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/src/CHANGELOG b/src/CHANGELOG
index f889d61..0ad0e44 100644
--- a/src/CHANGELOG
+++ b/src/CHANGELOG
@@ -1,3 +1,9 @@
+1.8.0.0
+ * Bug 9387: Provide a "Security Slider" for vulnerability surface reduction
+ * Bug 13019: Synchronize locale spoofing pref with our Firefox patch
+ * Bug 3455: Use SOCKS user+pass to isolate all requests from the same url domain
+ * Bug 8641: Create browser UI to indicate current tab's Tor circuit IPs
+
1.7.0.1
* Bug 13378: Prevent addon reordering in toolbars on first-run.
diff --git a/src/install.rdf b/src/install.rdf
index b4af033..4148b3c 100644
--- a/src/install.rdf
+++ b/src/install.rdf
@@ -6,7 +6,7 @@
<em:name>Torbutton</em:name>
<em:creator>Mike Perry</em:creator>
<em:id>torbutton(a)torproject.org</em:id>
- <em:version>1.7.0.1</em:version>
+ <em:version>1.8.0.0</em:version>
<em:homepageURL>https://www.torproject.org/projects/torbrowser.html.en</em:homepageURL>
<em:optionsURL>chrome://torbutton/content/preferences.xul</em:optionsURL>
<em:iconURL>chrome://torbutton/skin/tor.png</em:iconURL>
1
0

31 Oct '14
commit 818f9b0a076dc31cc87544227aea164b07235276
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Thu Oct 30 17:47:47 2014 -0700
Update translations from transifex.
---
src/chrome/locale/fa/torbutton.properties | 2 +-
src/chrome/locale/pt/aboutTor.dtd | 12 ++++++------
src/chrome/locale/sv/aboutTor.dtd | 2 +-
src/chrome/locale/sv/brand.dtd | 8 ++++----
src/chrome/locale/sv/brand.properties | 12 ++++++------
src/chrome/locale/sv/torbutton.dtd | 4 ++--
src/chrome/locale/sv/torbutton.properties | 14 +++++++-------
src/chrome/locale/tr/aboutTor.dtd | 2 +-
src/chrome/locale/tr/browser.properties | 4 ++--
src/chrome/locale/tr/torbutton.dtd | 20 ++++++++++----------
src/chrome/locale/tr/torbutton.properties | 2 +-
11 files changed, 41 insertions(+), 41 deletions(-)
diff --git a/src/chrome/locale/fa/torbutton.properties b/src/chrome/locale/fa/torbutton.properties
index 811125e..265aa65 100644
--- a/src/chrome/locale/fa/torbutton.properties
+++ b/src/chrome/locale/fa/torbutton.properties
@@ -48,7 +48,7 @@ torbutton.popup.confirm_plugins = پلاگینها مانند فلش، میتو
torbutton.popup.never_ask_again = دیگر هیچگاه این را از من نپرس
# Canvas permission prompt. Strings are kept here for ease of translation.
-canvas.siteprompt=This website (%S) attempted to extract HTML5 canvas image data, which may be used to uniquely identify your computer.\n\nShould Tor Browser allow this website to extract HTML5 canvas image data?
+canvas.siteprompt=این وبسایت (%S) سعی دارد اطلاعات بوم تصویر HTML5 را دریافت کند که ممکن است برای شناسایی منحصر به فرد کامپیوتر شما استفاده شود.\n\nآیا مرورگر تور میبایست اجازه دریافت این اطلاعات را بدهد؟
canvas.notNow=نه در حال حاضر
canvas.notNowAccessKey=N
canvas.allow=اجازه دهید در آینده
diff --git a/src/chrome/locale/pt/aboutTor.dtd b/src/chrome/locale/pt/aboutTor.dtd
index dbff853..fd5cea7 100644
--- a/src/chrome/locale/pt/aboutTor.dtd
+++ b/src/chrome/locale/pt/aboutTor.dtd
@@ -21,7 +21,7 @@
<!ENTITY aboutTor.failure3Link "help(a)rt.torproject.org">
<!ENTITY aboutTor.failure3suffix.label ".">
-<!ENTITY aboutTor.search.label "Procurar">
+<!ENTITY aboutTor.search.label "Pesquisar">
<!ENTITY aboutTor.searchSPPost.link "https://startpage.com/rth/search">
<!ENTITY aboutTor.searchDDGPost.link "https://duckduckgo.com/html/">
@@ -31,16 +31,16 @@
<!ENTITY aboutTor.torInfo3.label "Nó de saída:">
<!ENTITY aboutTor.torInfo4.label "Este servidor não guarda informação dos visitantes.">
<!ENTITY aboutTor.whatnextQuestion.label "O que se segue?">
-<!ENTITY aboutTor.whatnextAnswer.label "Só por isso, o Tor não chega para navegar anónimamente na internet! Poderá ter que mudar alguns dos seus hábitos de navegação para ter a certeza que a sua identidade está segura.">
+<!ENTITY aboutTor.whatnextAnswer.label "O Tor NÃO é tudo o que precisa para navegar anonimamente na internet! Poderá ter que mudar alguns dos seus hábitos de navegação para ter a certeza que a sua identidade está segura.">
<!ENTITY aboutTor.whatnext.label "Dicas sobre como se tornar anónimo »">
<!ENTITY aboutTor.whatnext.link "https://www.torproject.org/download/download.html.en#warning">
-<!ENTITY aboutTor.helpInfo1.label "Todos podem ajudar!">
+<!ENTITY aboutTor.helpInfo1.label "Você pode ajudar!">
<!ENTITY aboutTor.helpInfo2.label "Há muitas maneiras para ajudar a rede Tor tornar-se mais rápida e forte:">
-<!ENTITY aboutTor.helpInfo3.label "Pôr de pé um Nó de Relay Tor »">
+<!ENTITY aboutTor.helpInfo3.label "Criar um Nó de Relay Tor »">
<!ENTITY aboutTor.helpInfo3.link "https://www.torproject.org/docs/tor-doc-relay.html.en">
-<!ENTITY aboutTor.helpInfo4.label "Voluntariar os seus Serviços »">
+<!ENTITY aboutTor.helpInfo4.label "Voluntarie os seus serviços »">
<!ENTITY aboutTor.helpInfo4.link "https://www.torproject.org/getinvolved/volunteer.html.en">
-<!ENTITY aboutTor.helpInfo5.label "Fazer uma doação »">
+<!ENTITY aboutTor.helpInfo5.label "Faça um donativo »">
<!ENTITY aboutTor.helpInfo5.link "https://www.torproject.org/donate/donate.html.en">
<!ENTITY aboutTor.footer.label "O Projeto Tor é uma organização sem fins lucrativos US 501(c)(3) dedicada à investigação, desenvolvimento e promoção de anonimidade e privacidade online.">
diff --git a/src/chrome/locale/sv/aboutTor.dtd b/src/chrome/locale/sv/aboutTor.dtd
index d3b5e1f..7fd6957 100644
--- a/src/chrome/locale/sv/aboutTor.dtd
+++ b/src/chrome/locale/sv/aboutTor.dtd
@@ -28,7 +28,7 @@
<!ENTITY aboutTor.torInfo1.label "Ytterligare information:">
<!ENTITY aboutTor.torInfo2.label "Land och IP-adress:">
-<!ENTITY aboutTor.torInfo3.label "Exit nod:">
+<!ENTITY aboutTor.torInfo3.label "Exitnod:">
<!ENTITY aboutTor.torInfo4.label "Den här servern sparar inte någon information om besökare.">
<!ENTITY aboutTor.whatnextQuestion.label "Och nu då?">
<!ENTITY aboutTor.whatnextAnswer.label "Tor är INTE allt som behövs för att vara anonym på nätet! Du behöver kanske ändra några av dina vanor för att försäkra att din identitet förblir skyddad.">
diff --git a/src/chrome/locale/sv/brand.dtd b/src/chrome/locale/sv/brand.dtd
index 454646f..312a603 100644
--- a/src/chrome/locale/sv/brand.dtd
+++ b/src/chrome/locale/sv/brand.dtd
@@ -2,7 +2,7 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-<!ENTITY brandShortName "Tor webbläsaren">
-<!ENTITY brandFullName "Tor webbläsaren">
-<!ENTITY vendorShortName "Tor projektet">
-<!ENTITY trademarkInfo.part1 "Firefox och Firefox logotypen är varumärken tillhörande Mozilla Foundation.">
+<!ENTITY brandShortName "Tor Browser">
+<!ENTITY brandFullName "Tor Browser">
+<!ENTITY vendorShortName "Tor-projektet">
+<!ENTITY trademarkInfo.part1 "Firefox och Firefox-logotypen är varumärken som tillhör Mozilla Foundation.">
diff --git a/src/chrome/locale/sv/brand.properties b/src/chrome/locale/sv/brand.properties
index 5212773..ae59c81 100644
--- a/src/chrome/locale/sv/brand.properties
+++ b/src/chrome/locale/sv/brand.properties
@@ -2,14 +2,14 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-brandShortName=Tor webbläsaren
-brandFullName=Tor webbläsaren
-vendorShortName=Tor projektet
+brandShortName=Tor Browser
+brandFullName=Tor Browser
+vendorShortName=Tor Browser
homePageSingleStartMain=Firefox Start, en snabb hemsida med inbyggd sökfunktion
-homePageImport=Importera din hemsida från %S
+homePageImport=Importera din startsida från %S
-homePageMigrationPageTitle=Val av hemsida
-homePageMigrationDescription=Välj den hemsida du önskar använda:
+homePageMigrationPageTitle=Val av startsida
+homePageMigrationDescription=Välj den startsida du vill använda:
syncBrandShortName=Synka
diff --git a/src/chrome/locale/sv/torbutton.dtd b/src/chrome/locale/sv/torbutton.dtd
index fa580d4..67aafe8 100644
--- a/src/chrome/locale/sv/torbutton.dtd
+++ b/src/chrome/locale/sv/torbutton.dtd
@@ -103,7 +103,7 @@
<!ENTITY torbutton.prefs.block_nontor_file_net "Blockera Icke-Tor tillgång till nätverk från file:// länkar">
<!ENTITY torbutton.prefs.restore_defaults "Återställ till standard">
<!ENTITY torbutton.prefs.test_settings "Testa inställningar">
-<!ENTITY torbutton.prefs.test_auto "Testa mina Tor inställningar efter första gången jag växlar vid varje Firefox start">
+<!ENTITY torbutton.prefs.test_auto "Testa mina Tor-inställningar efter första gången jag växlar vid varje start av Firefox">
<!ENTITY torbutton.prefs.disable_livemarks "Disable livemarks updates during Tor usage">
<!ENTITY torbutton.prefs.tor_memory_jar "Skriv inte Tor kakor till disken">
<!ENTITY torbutton.prefs.nontor_memory_jar "Skriv inte Icke-Tor kakor till disken">
@@ -135,7 +135,7 @@
<!ENTITY torbutton.prefs.dtd_recommended "(rekommenderat)">
<!ENTITY torbutton.prefs.dtd_optional "(valfritt)">
<!ENTITY torbutton.prefs.dtd_crucial "(viktigt)">
-<!ENTITY torbutton.prefs.update_torbutton_via_tor "Dirigera om Torbutton uppdateringar genom Tor">
+<!ENTITY torbutton.prefs.update_torbutton_via_tor "Dirigera om Torbutton-uppdateringar genom Tor">
<!ENTITY torbutton.prefs.dodge_google_captcha "Använd automatiskt en alternativ sökmotor när du presenteras med en Google Captcha:">
<!ENTITY torbutton.prefs.engine1 "ixquick.com">
<!ENTITY torbutton.prefs.engine2 "Bing.com">
diff --git a/src/chrome/locale/sv/torbutton.properties b/src/chrome/locale/sv/torbutton.properties
index d1cc52a..d55e43a 100644
--- a/src/chrome/locale/sv/torbutton.properties
+++ b/src/chrome/locale/sv/torbutton.properties
@@ -17,7 +17,7 @@ torbutton.popup.test.failure = Tor proxy MISSLYCKADES! Kontrollera din proxy och
torbutton.popup.test.confirm_toggle = Det senaste Tor proxy testet misslyckades att använda Tor.\n\nÄr du säker att du vill aktivera ändå?\n\nNotera: Om du fixat problemet kan du köra om testet i Torbuttons Proxy Preferenser för att eliminera denna varning.
torbutton.popup.test.ff3_notice = Klicka på OK för att testa Tors proxyinställningar. Detta test kommer att ske i bakgrunden. Ha tålamod.
torbutton.panel.label.verified = Tor verifierad
-torbutton.popup.test.auto_failed = Den automatiska Tor proxy misslyckades att använda Tor.\n\nÄr du säker på att du vill aktivera ändå?
+torbutton.popup.test.auto_failed = Den automatiska Tor-proxyn misslyckades att använda Tor.\n\nÄr du säker på att du vill aktivera ändå?
torbutton.prefs.recommended = (rekommenderat)
torbutton.prefs.optional = (valfritt)
torbutton.prefs.crucial = (kritiskt)
@@ -30,19 +30,19 @@ torbutton.popup.cancel = Avbryt
torbutton.popup.dontask = Hämta hem filer automatiskt i fortsättningen
torbutton.popup.test.no_http_proxy = Tor proxy test: Lokal HTTP Proxy är onåbar. Är Polipo igång ordentligt?
torbutton.popup.captcha.title = Undvik Google Captchas?
-torbutton.popup.captcha.ask = Torbutton upptäckte en Google Captcha. Vill du att omdirigeras till en annan sökmotor för den här frågan?
+torbutton.popup.captcha.ask = Torbutton upptäckte en Google Captcha. Vill du omdirigeras till en annan sökmotor för den här frågan?
torbutton.popup.captcha.always = Utför alltid denna åtgärd från och med nu
torbutton.popup.redirect = Omdirigera
torbutton.popup.no_redirect = Omdirigera inte
-torbutton.popup.prompted_language = För att ge dig mer privatliv kan Torbutton begära en Engelsk version av webbsidor. Detta kan göra att webbsidor som du föredrar att läsa på ett annat språk visas på Engelska istället.\\\n\\\n Vill du visa sidor på Engelska för bättre privatliv?
+torbutton.popup.prompted_language = För ett bättre integritetsskydd kan Torbutton begära den engelska versionen av webbsidor. Detta kan göra att webbsidor som du föredrar att läsa på ditt modersmål visas på engelska istället.\\\n\\\n Vill du visa sidor på engelska för att få ett bättre integritetsskydd?
torbutton.popup.no_newnym = Torbutton kan inte säkert ge dig en ny identitet. Det har inte tillgång till Tor Control Port.\n\nKör du Tor Browser Bundle?
-torbutton.popup.use_tbb = Det verkar som om du använder Torknappen med Firefox, vilket inte längre är en rekommenderad säker konfiguration.\n\nIstället rekommenderar vi dig att ladda ner den senaste Tor Browser Bundle genom att skicka ett mail till gettor(a)torproject.org eller ladda ner den på följande URL:
+torbutton.popup.use_tbb = Det verkar som om du använder Torbutton med Firefox, vilket inte längre är en rekommenderad säker konfiguration.\n\nIstället rekommenderar vi dig att ladda ner den senaste Tor Browser Bundle genom att skicka ett mail till gettor(a)torproject.org eller ladda ner den på följande URL:
torbutton.popup.pref_error = Torbutton kan inte uppdatera inställningar i Tor Browser profilen katalog.
torbutton.popup.permission_denied = Du antingen återställa behörigheterna Tor Browser katalogen eller kopiera den till en ny plats.
torbutton.popup.device_full = Skivan verkar vara full. Vänligen frigöra utrymme eller flytta Tor webbläsare till en ny enhet.
-torbutton.title.prompt_torbrowser = Viktig Torbutton Information
-torbutton.popup.prompt_torbrowser = Torbutton fungerar annorlunda nu: Du kan inte slå av den längre.\n\nVi gjorde denna förändring eftersom det inte är säkert att använda Torbutton i en webbläsare som också används för icke-Tor surfning. Det var för många buggar som vi inte kunde fixa på något annat sätt.\n\nOm du vill fortsätta använda Firefox normalt så bör du avinstallera Torknappen och ladda ner Tor Browser Bundle. Tor Webbläsaren skyddar ditt privatliv bättre än vanliga Firefox, även när Firefox används med Torknappen.\n\nFör att ta bort Torbutton, gå till Verktyg->Tillägg->Tillägg och klicka på Ta Bort knappen bredvid Torknappen.
-torbutton.popup.short_torbrowser = Viktig Torbutton information!\n\nTorbutton är nu alltid aktiverad.\n\nKlicka på Torbutton för mer information.
+torbutton.title.prompt_torbrowser = Viktig information om Torbutton
+torbutton.popup.prompt_torbrowser = Torbutton fungerar annorlunda nu: Du kan inte slå av den längre.\n\nVi gjorde denna förändring eftersom det inte är säkert att använda Torbutton i en webbläsare som också används för icke-Tor surfning. Det var för många buggar som vi inte kunde fixa på något annat sätt.\n\nOm du vill fortsätta använda Firefox normalt så bör du avinstallera Tor Browser och ladda ner Tor Browser Bundle. Tor Browser skyddar ditt privatliv bättre än vanliga Firefox, även när Firefox används med Tor Browser.\n\nFör att ta bort Torbutton, gå till Verktyg->Tillägg->Tillägg och klicka på Ta bort-knappen bredvid Torbutton.
+torbutton.popup.short_torbrowser = Viktig information om Torbutton!\n\nTorbutton är nu alltid aktiverad.\n\nKlicka på Torbutton för mer information.
torbutton.popup.confirm_plugins = Insticksmoduler så som Flash kan äventyra din anonymitet och personliga integritet.\n\nDe kan också kringgå Tor för att avslöja var du befinner dig och vad din IP-adress är.\n\nÄr du säker på att du vill aktivera insticksmoduler?\n\n
torbutton.popup.never_ask_again = Fråga aldrig igen
diff --git a/src/chrome/locale/tr/aboutTor.dtd b/src/chrome/locale/tr/aboutTor.dtd
index 6e072c3..5e6e3e5 100644
--- a/src/chrome/locale/tr/aboutTor.dtd
+++ b/src/chrome/locale/tr/aboutTor.dtd
@@ -8,7 +8,7 @@
<!ENTITY aboutTor.outOfDateTorOn.label "AMA, bu tarayıcı güncel değil.">
<!ENTITY aboutTor.outOfDateTorOff.label "AYRICA, bu tarayıcı güncel değil.">
-<!ENTITY aboutTor.outOfDate2.label "Soğan'a tıklayın ve Tor Tarayıcı'yı güncelleyin.">
+<!ENTITY aboutTor.outOfDate2.label "Soğana tıklayın ve Tor Tarayıcı Paketi Güncellemesini İndir seçin.">
<!ENTITY aboutTor.check.label "Tor Ağ ayarlarını test edin">
diff --git a/src/chrome/locale/tr/browser.properties b/src/chrome/locale/tr/browser.properties
index c30bc36..295a03a 100644
--- a/src/chrome/locale/tr/browser.properties
+++ b/src/chrome/locale/tr/browser.properties
@@ -5,9 +5,9 @@ browser.startup.homepage=about:tor
spellchecker.dictionary=en_US
# Default search engine
-browser.search.defaultenginename=BaşlagıçSayfası
+browser.search.defaultenginename=Startpage
# Search engine order (order displayed in the search bar dropdown)
-browser.search.order.1=BaşlagıçSayfası
+browser.search.order.1=Startpage
browser.search.order.2=DuckDuckGo
browser.search.order.3=Google
diff --git a/src/chrome/locale/tr/torbutton.dtd b/src/chrome/locale/tr/torbutton.dtd
index e469873..f2f1762 100644
--- a/src/chrome/locale/tr/torbutton.dtd
+++ b/src/chrome/locale/tr/torbutton.dtd
@@ -11,7 +11,7 @@
<!ENTITY torbutton.prefs.proxy.host.socks "SOCKS Sunucusu:">
<!ENTITY torbutton.prefs.proxy.port "Bağl. Nok.:">
<!ENTITY torbutton.about.title "Torbutton Hakkında">
-<!ENTITY torbutton.about.version "Versiyon:">
+<!ENTITY torbutton.about.version "Sürüm:">
<!ENTITY torbutton.about.summary "Tor tarama gizliliğinizi korur.">
<!ENTITY torbutton.about.code "Kodlarda yardımı bulunanlar:">
<!ENTITY torbutton.about.maintainer "Bakımcı:">
@@ -32,7 +32,7 @@
<!ENTITY torbutton.context_menu.about.key "H">
<!ENTITY torbutton.context_menu.networksettings "Ağ Ayarlarını Aç...">
<!ENTITY torbutton.context_menu.networksettings.key "S">
-<!ENTITY torbutton.context_menu.downloadUpdate "Tor Tarayıcı Destesi güncelleştirmesini yükleyin.">
+<!ENTITY torbutton.context_menu.downloadUpdate "Tor Tarayıcı Paketi Güncelleştirmesini İndirin.">
<!ENTITY torbutton.context_menu.downloadUpdate.key "H">
<!ENTITY torbutton.context_menu.cookieProtections "Çerez Korumaları">
<!ENTITY torbutton.context_menu.cookieProtections.key "C">
@@ -121,14 +121,14 @@
<!ENTITY torbutton.prefs.spoofdomain "Referans olarak alanı aldat">
<!ENTITY torbutton.prefs.spoofblank "Spoof blank referer during Tor usage (may break some sites)">
<!ENTITY torbutton.cookiedialog.title "Çerez Korumasını Yönet">
-<!ENTITY torbutton.cookiedialog.lockCol "Korunmuş">
+<!ENTITY torbutton.cookiedialog.lockCol "Korunan">
<!ENTITY torbutton.cookiedialog.domainCol "Sunucu">
<!ENTITY torbutton.cookiedialog.nameCol "İsim">
<!ENTITY torbutton.cookiedialog.pathCol "Yol">
-<!ENTITY torbutton.cookiedialog.protectCookie "Çerezi sakla">
-<!ENTITY torbutton.cookiedialog.removeCookie "Çerezi sil">
-<!ENTITY torbutton.cookiedialog.unprotectCookie "Çerezi korumayı sonlandır">
-<!ENTITY torbutton.cookiedialog.removeAllBut "Korunanlar hariç tümünü sil">
+<!ENTITY torbutton.cookiedialog.protectCookie "Çerezi Koru">
+<!ENTITY torbutton.cookiedialog.removeCookie "Çerezi Sil">
+<!ENTITY torbutton.cookiedialog.unprotectCookie "Çerezi Korumayı Sonlandır">
+<!ENTITY torbutton.cookiedialog.removeAllBut "Korunanlar Hariç Tümünü Sil">
<!ENTITY torbutton.cookiedialog.saveAllCookies "Yeni çerezleri koru">
<!ENTITY torbutton.cookiedialog.doNotSaveAllCookies "Yeni çerezleri koruma">
<!ENTITY torbutton.prefs.disable_livemarks "Disable livemarks updates during Tor usage">
@@ -145,6 +145,6 @@
<!ENTITY torbutton.prefs.fix_google_srch "Kaldır platform ve Google Arama Kutusu gelen dil sorgular">
<!ENTITY torbutton.prefs.transparentTor "Şeffaf Torifikasyon (özel transproxy veya Tor yönlendiricisi gerekir)">
<!ENTITY torbutton.prefs.block_disk "Tarama geçmişini ve web sitesi bilgilerini kaydetme (Özel Tarama Kipi'ni etkinleştirir)">
-<!ENTITY torbutton.prefs.restrict_thirdparty "3. parti çerezleri ve diğer iz sürücü bilgileri engelle.">
-<!ENTITY torbutton.prefs.block_plugins "Flash gibi tarayıcı eklentilerini engelle.">
-<!ENTITY torbutton.prefs.resist_fingerprinting "Diğer Tor kullanıcılardan sizi ayıran detayları değiştirin.">
+<!ENTITY torbutton.prefs.restrict_thirdparty "3. parti çerezleri ve diğer iz sürücü bilgileri engelle">
+<!ENTITY torbutton.prefs.block_plugins "Tarayıcı eklentilerini engelle (Flash benzeri)">
+<!ENTITY torbutton.prefs.resist_fingerprinting "Diğer Tor kullanıcılardan sizi ayıran detayları değiştir">
diff --git a/src/chrome/locale/tr/torbutton.properties b/src/chrome/locale/tr/torbutton.properties
index b857f82..5a39ac2 100644
--- a/src/chrome/locale/tr/torbutton.properties
+++ b/src/chrome/locale/tr/torbutton.properties
@@ -34,7 +34,7 @@ torbutton.popup.captcha.ask = Google Captcha algılandı. Aramana devam etmek i
torbutton.popup.captcha.always = Bu ayarı şu andan itibaren sürekli hale getir\n
torbutton.popup.redirect = Yönlendir
torbutton.popup.no_redirect = Yönlendirme
-torbutton.popup.prompted_language = Daha fazla gizlilik icin, Torbutton sayfaların İngilizce versiyonlarını göstermeye çalışır. Bu özellik sayfaları ana dilinizde görememenize sebep olabilir.\n\nSiz de daha fazla gizlilik için sayfaların İngilizce sürümlerini görüntülemek ister misiniz?
+torbutton.popup.prompted_language = Daha fazla gizlilik icin, Torbutton sayfaların İngilizce sürümlerini göstermeyi talep edebilir. Bu özellik, sayfaların ana diliniz yerine İngilizce görüntülenmesine sebep olabilir.\n\nDaha iyi gizlilik için sayfaların İngilizce sürümlerinin talep edilmesini ister misiniz?
torbutton.popup.no_newnym = Torbutton size güvenli yeni bir kimlik sağlayamadı. Tor Control Port una giriş yapılamıyor.\n\nTor Browser Bundle nin çalıştığından emin olun.
torbutton.popup.use_tbb = Görünüşe göre Torbutton'ı Firefox ile kullanıyorsunuz, bu tavsiye edilen bir güvenlik ayarlaması değildir.\n\nAslında, Size tavsiyemiz Tor Tarayıcısını gettor(a)torproject.org adresine e-posta göndererek veya şu adrese girerek edinmenizdir.
torbutton.popup.pref_error = Torbutton, Tor Browser profil klasörünün içinde seçenekleri güncelleyemez.
1
0

[tor-browser-bundle/master] Bump tor version to 0.2.6.1 in the alpha series.
by mikeperry@torproject.org 31 Oct '14
by mikeperry@torproject.org 31 Oct '14
31 Oct '14
commit a7de826b620d31992277d881484985d58af9540f
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Thu Oct 30 17:07:27 2014 -0700
Bump tor version to 0.2.6.1 in the alpha series.
---
gitian/versions.alpha | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gitian/versions.alpha b/gitian/versions.alpha
index 1e546bf..e218a24 100755
--- a/gitian/versions.alpha
+++ b/gitian/versions.alpha
@@ -9,7 +9,7 @@ FIREFOX_VERSION=31.2.0esr
TORBROWSER_UPDATE_CHANNEL=alpha
TORBROWSER_TAG=tor-browser-${FIREFOX_VERSION}-4.5-1-build1
-TOR_TAG=tor-0.2.5.10
+TOR_TAG=tor-0.2.6.1-alpha
TORLAUNCHER_TAG=0.2.7.0.1
TORBUTTON_TAG=1.7.0.1
HTTPSE_TAG=3.5.3 # XXX: HTTPSE_VER is used instead, pending #11630
1
0

[tor-browser-bundle/master] Fix Expert Bundle filename+version.
by mikeperry@torproject.org 31 Oct '14
by mikeperry@torproject.org 31 Oct '14
31 Oct '14
commit c74bb8b7ae32100a02471be4439aa92b001fdcf7
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Thu Oct 30 17:07:45 2014 -0700
Fix Expert Bundle filename+version.
---
gitian/mkbundle-windows.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gitian/mkbundle-windows.sh b/gitian/mkbundle-windows.sh
index 62e1c69..e950884 100755
--- a/gitian/mkbundle-windows.sh
+++ b/gitian/mkbundle-windows.sh
@@ -225,7 +225,7 @@ then
mkdir -p $WRAPPER_DIR/$TORBROWSER_VERSION/
cp -a build/out/*.exe $WRAPPER_DIR/$TORBROWSER_VERSION/ || exit 1
cp -a build/out/*.mar $WRAPPER_DIR/$TORBROWSER_VERSION/ || exit 1
- cp -a inputs/tor-win32-gbuilt.zip $WRAPPER_DIR/$TORBROWSER_VERSION/tor-win32-${TOR_TAG_ORIG}.zip || exit 1
+ cp -a inputs/tor-win32-gbuilt.zip $WRAPPER_DIR/$TORBROWSER_VERSION/tor-win32-${TOR_TAG_ORIG:4}.zip || exit 1
touch inputs/bundle-windows.gbuilt
else
echo
1
0

[tor-browser-bundle/master] Bug #13443: Update mingw-w64 for DirectShow com ptr fix.
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit 68f93d2963dcbf1e1cb3f91d3686f48a682b37ae
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Thu Oct 30 15:27:55 2014 -0700
Bug #13443: Update mingw-w64 for DirectShow com ptr fix.
---
gitian/versions.alpha | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gitian/versions.alpha b/gitian/versions.alpha
index c4b65c3..1e546bf 100755
--- a/gitian/versions.alpha
+++ b/gitian/versions.alpha
@@ -16,7 +16,7 @@ HTTPSE_TAG=3.5.3 # XXX: HTTPSE_VER is used instead, pending #11630
NSIS_TAG=v0.2
ZLIB_TAG=v1.2.8
LIBEVENT_TAG=release-2.0.21-stable
-MINGW_TAG=469ed5d227202b373409c8a3b4c1358be39b9983 # XXX: ???
+MINGW_TAG=e712bb8b106d059914388e6ccd93c584a6416082 # XXX: ???
PYPTLIB_TAG=pyptlib-0.0.6
OBFSPROXY_TAG=obfsproxy-0.2.12
FLASHPROXY_TAG=1.6
1
0

[tor-browser/tor-browser-31.2.0esr-4.5-1] fixup! TB4: Tor Browser's Firefox preference overrides.
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit ce192c7834a68d10d3c672ffb0fcef92941c74f8
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Thu Oct 30 15:25:05 2014 -0700
fixup! TB4: Tor Browser's Firefox preference overrides.
Bug #13443: We will be using a new mingw-w64 with a direct fix.
---
browser/app/profile/000-tor-browser.js | 3 ---
1 file changed, 3 deletions(-)
diff --git a/browser/app/profile/000-tor-browser.js b/browser/app/profile/000-tor-browser.js
index d8498b2..83b79b2 100644
--- a/browser/app/profile/000-tor-browser.js
+++ b/browser/app/profile/000-tor-browser.js
@@ -172,9 +172,6 @@ pref("security.tls.version.max", 3);
// POODLE hotfix: Disable SSLv3
pref("security.tls.version.min", 1);
-// Bug 13443: Disable DirectShow to prevent crashing on windows
-pref("media.directshow.enabled", false);
-
#ifdef TOR_BROWSER_VERSION
#expand pref("torbrowser.version", __TOR_BROWSER_VERSION__);
#endif
1
0

[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

[torbutton/master] Merge remote-tracking branch 'gk/bug_9387_test_02'
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit bd5be6801b3bd2ac19e9f7dad98f229d32a82224
Merge: 2c2c5a8 cda1d6c
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Thu Oct 30 15:17:59 2014 -0700
Merge remote-tracking branch 'gk/bug_9387_test_02'
src/chrome/content/preferences.js | 37 +++++++
src/chrome/content/preferences.xul | 62 +++++++++--
src/chrome/content/torbutton.js | 177 +++++++++++++++++++++++++++++++
src/chrome/locale/en/torbutton.dtd | 9 +-
src/defaults/preferences/preferences.js | 3 +
5 files changed, 276 insertions(+), 12 deletions(-)
1
0

[torbutton/master] Bug #8641: TorButton popup menu that displays current Tor circuit
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit 2c2c5a8aceae44c68915e8fe33bc3865f00b535c
Author: Arthur Edelstein <arthuredelstein(a)gmail.com>
Date: Fri Aug 1 23:28:06 2014 -0700
Bug #8641: TorButton popup menu that displays current Tor circuit
---
src/chrome.manifest | 3 +-
src/chrome/content/popup.xul | 33 +-
src/chrome/content/tor-circuit-display.js | 185 ++++++++++
src/chrome/content/torbutton.js | 2 +
src/chrome/content/torbutton.xul | 1 +
src/chrome/skin/torbutton.css | 15 +
src/modules/tor-control-port.js | 575 +++++++++++++++++++++++++++++
7 files changed, 809 insertions(+), 5 deletions(-)
diff --git a/src/chrome.manifest b/src/chrome.manifest
index d211984..2ab3c8f 100644
--- a/src/chrome.manifest
+++ b/src/chrome.manifest
@@ -3,6 +3,7 @@ overlay chrome://browser/content/browser.xul chrome://torbutton/content/torbutto
overlay chrome://browser/content/preferences/connection.xul chrome://torbutton/content/pref-connection.xul
overlay chrome://messenger/content/messenger.xul chrome://torbutton/content/torbutton_tb.xul
overlay chrome://messenger/content/messengercompose/messengercompose.xul chrome://torbutton/content/torbutton_tb.xul
+resource torbutton ./
# browser branding
override chrome://branding/locale/brand.dtd chrome://torbutton/locale/brand.dtd
@@ -161,4 +162,4 @@ contract @torproject.org/domain-isolator;1 {e33fd6d4-270f-475f-a96f-ff3140279f68
category profile-after-change CookieJarSelector @torproject.org/cookie-jar-selector;1
category profile-after-change TBSessionBlocker @torproject.org/torbutton-ss-blocker;1
category profile-after-change StartupObserver @torproject.org/startup-observer;1
-category profile-after-change DomainIsolator @torproject.org/domain-isolator;1
\ No newline at end of file
+category profile-after-change DomainIsolator @torproject.org/domain-isolator;1
diff --git a/src/chrome/content/popup.xul b/src/chrome/content/popup.xul
index 3ee953b..2965ec5 100644
--- a/src/chrome/content/popup.xul
+++ b/src/chrome/content/popup.xul
@@ -9,14 +9,16 @@
<stringbundleset id="torbutton-stringbundleset">
<stringbundle id="torbutton-bundle" src="chrome://torbutton/locale/torbutton.properties"/>
</stringbundleset>
- <menupopup id="torbutton-context-menu" onpopupshowing="torbutton_check_protections();"
- anchor="torbutton-button" position="after_start">
+ <panel id="torbutton-context-menu" onpopupshowing="torbutton_check_protections();" titlebar="normal" noautohide="true"
+ anchor="torbutton-button" position="after_start" >
+ <hbox align="start">
+ <vbox>
<menuitem id="torbutton-new-identity"
label="&torbutton.context_menu.new_identity;"
accesskey="&torbutton.context_menu.new_identity_key;"
insertafter="context-stop"
oncommand="torbutton_new_identity()"/>
- <menuitem id="torbutton-cookie-protector"
+ <menuitem id="torbutton-cookie-protector"
label="&torbutton.context_menu.cookieProtections;"
accesskey="&torbutton.context_menu.cookieProtections.key;"
insertafter="context-stop"
@@ -42,6 +44,29 @@
insertafter="context-stop"
oncommand="torbutton_download_update()"
hidden="true"/>
- </menupopup>
+ </vbox>
+ <vbox>
+ <!-- The following SVG is used to display a Tor circuit diagram for the current tab.
+ It is not displayed unless activated by tor-circuit-display.js. -->
+ <svg xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="full"
+ width="290" height="140" id="tor-circuit" style="display:none;">
+ <rect x="0" y="0" width="100%" height="100%" fill="#e8f4f4" />
+ <text id="title" style="font-size:14px;font-weight:bold;" x="10" y="20" fill="#2c26a7">Tor circuit for this site</text>
+ <text id="domain" style="font-size:13px;" x="10" y="38" fill="black">(trac.torproject.org)</text>
+ <rect x="18.5" width="3" y="56" height="64" fill="#4d363a" stroke-width="0"/>
+ <circle class="node-circle" cx="20" cy="56" r="4" />
+ <text class="node-text" x="32" y="56">This Browser</text>
+ <circle class="node-circle" cx="20" cy="72" r="4" />
+ <text class="node-text" x="32" y="72">Test123 (54.67.87.34)</text>
+ <circle class="node-circle" cx="20" cy="88" r="4" />
+ <text class="node-text" x="32" y="88">TestABC (121.4.56.67)</text>
+ <circle class="node-circle" cx="20" cy="104" r="4" />
+ <text class="node-text" x="32" y="104">TestXYZ (74.3.30.9)</text>
+ <circle class="node-circle" cx="20" cy="120" r="4" />
+ <text class="node-text" x="32" y="120">Internet</text>
+ </svg>
+ </vbox>
+ </hbox>
+ </panel>
</overlay>
diff --git a/src/chrome/content/tor-circuit-display.js b/src/chrome/content/tor-circuit-display.js
new file mode 100644
index 0000000..5f4d8bf
--- /dev/null
+++ b/src/chrome/content/tor-circuit-display.js
@@ -0,0 +1,185 @@
+// A script that automatically displays the Tor Circuit used for the
+// current domain for the currently selected tab.
+//
+// This file is written in call stack order (later functions
+// call earlier functions). The file can be processed
+// with docco.js to produce pretty documentation.
+//
+// This script is to be embedded in torbutton.xul. It defines a single global function,
+// runTorCircuitDisplay(host, port, password), which activates the automatic Tor
+// circuit display for the current tab and any future tabs.
+//
+// See https://trac.torproject.org/8641
+
+/* jshint esnext: true */
+/* global document, gBrowser, Components */
+
+// ### Main function
+// __runTorCircuitDisplay(host, port, password)__.
+// The single function we run to activate automatic display of the Tor circuit..
+let runTorCircuitDisplay = (function () {
+
+"use strict";
+
+// Mozilla utilities
+const Cu = Components.utils;
+Cu.import("resource://gre/modules/Services.jsm");
+
+// Import the controller code.
+let { controller } = Cu.import("resource://torbutton/modules/tor-control-port.js");
+
+// Make the TorButton logger available.
+let logger = Cc["@torproject.org/torbutton-logger;1"]
+ .getService(Components.interfaces.nsISupports).wrappedJSObject;
+
+// __regionBundle__.
+// A list of localized region (country) names.
+let regionBundle = Services.strings.createBundle(
+ "chrome://global/locale/regionNames.properties");
+
+// __localizedCountryNameFromCode(countryCode)__.
+// Convert a country code to a localized country name.
+// Example: `'de'` -> `'Deutschland'` in German locale.
+let localizedCountryNameFromCode = function (countryCode) {
+ try {
+ return regionBundle.GetStringFromName(countryCode.toLowerCase());
+ } catch (e) {
+ return countryCode.toUpperCase();
+ }
+};
+
+// __domainToNodeDataMap__.
+// A mutable map that stores the current nodes for each domain.
+let domainToNodeDataMap = {};
+
+// __trimQuotes(s)__.
+// Removes quotation marks around a quoted string.
+let trimQuotes = s => s.match(/^\"(.*)\"$/)[1];
+
+// nodeDataForID(controller, id, onResult)__.
+// Requests the IP, country code, and name of a node with given ID.
+// Returns result via onResult.
+// Example: nodeData(["20BC91DC525C3DC9974B29FBEAB51230DE024C44"], show);
+let nodeDataForID = function (controller, ids, onResult) {
+ let idRequests = ids.map(id => "ns/id/" + id);
+ controller.getInfoMultiple(idRequests, function (statusMaps) {
+ let IPs = statusMaps.map(statusMap => statusMap.IP),
+ countryRequests = IPs.map(ip => "ip-to-country/" + ip);
+ controller.getInfoMultiple(countryRequests, function (countries) {
+ let results = [];
+ for (let i = 0; i < ids.length; ++i) {
+ results.push({ name : statusMaps[i].nickname, id : ids[i] ,
+ ip : statusMaps[i].IP , country : countries[i] });
+ }
+ onResult(results);
+ });
+ });
+};
+
+// __nodeDataForCircuit(controller, circuitEvent, onResult)__.
+// Gets the information for a circuit.
+let nodeDataForCircuit = function (controller, circuitEvent, onResult) {
+ let ids = circuitEvent.circuit.map(circ => circ[0]);
+ nodeDataForID(controller, ids, onResult);
+};
+
+// __nodeLines(nodeData)__.
+// Takes a nodeData array of three items each like
+// `{ ip : "12.34.56.78", country : "fr" }`
+// and converts each node data to text, as
+// `"France (12.34.56.78)"`.
+let nodeLines = function (nodeData) {
+ let result = ["This browser"];
+ for (let {ip, country} of nodeData) {
+ result.push(localizedCountryNameFromCode(country) + " (" + ip + ")");
+ }
+ result.push("Internet");
+ return result;
+};
+
+// __updateCircuitDisplay()__.
+// Updates the Tor circuit display SVG, showing the current domain
+// and the relay nodes for that domain.
+let updateCircuitDisplay = function () {
+ let URI = gBrowser.selectedBrowser.currentURI,
+ domain = null,
+ nodeData = null;
+ // Try to get a domain for this URI. Otherwise it remains null.
+ try {
+ domain = URI.host;
+ } catch (e) { }
+ if (domain) {
+ // Check if we have anything to show for this domain.
+ nodeData = domainToNodeDataMap[domain];
+ if (nodeData) {
+ // Update the displayed domain.
+ document.querySelector("svg#tor-circuit text#domain").innerHTML = "(" + domain + "):";
+ // Update the displayed information for the relay nodes.
+ let diagramNodes = document.querySelectorAll("svg#tor-circuit text.node-text"),
+ lines = nodeLines(nodeData);
+ for (let i = 0; i < diagramNodes.length; ++i) {
+ diagramNodes[i].innerHTML = lines[i];
+ }
+ }
+ }
+ // Only show the Tor circuit if we have a domain and node data.
+ document.querySelector("svg#tor-circuit").style.display = (domain && nodeData) ?
+ 'block' : 'none';
+};
+
+// __collectBuiltCircuitData(aController)__.
+// Watches for CIRC BUILT events and records their data in the domainToNodeDataMap.
+let collectBuiltCircuitData = function (aController) {
+ aController.watchEvent(
+ "CIRC",
+ circuitEvent => circuitEvent.status === "EXTENDED" ||
+ circuitEvent.status === "BUILT",
+ function (circuitEvent) {
+ let domain = trimQuotes(circuitEvent.SOCKS_USERNAME);
+ if (domain) {
+ nodeDataForCircuit(aController, circuitEvent, function (nodeData) {
+ domainToNodeDataMap[domain] = nodeData;
+ updateCircuitDisplay();
+ });
+ } else {
+ updateCircuitDisplay();
+ }
+ });
+};
+
+// __syncDisplayWithSelectedTab()__.
+// We may have multiple tabs, but there is only one instance of TorButton's popup
+// panel for displaying the Tor circuit UI. Therefore we need to update the display
+// to show the currently selected tab at its current location.
+let syncDisplayWithSelectedTab = function () {
+ // Whenever a different tab is selected, change the circuit display
+ // to show the circuit for that tab's domain.
+ gBrowser.tabContainer.addEventListener("TabSelect", function (event) {
+ updateCircuitDisplay();
+ });
+ // If the currently selected tab has been sent to a new location,
+ // update the circuit to reflect that.
+ gBrowser.addTabsProgressListener({ onLocationChange : function (aBrowser) {
+ if (aBrowser == gBrowser.selectedBrowser) {
+ updateCircuitDisplay();
+ }
+ } });
+
+ // Get started with a correct display.
+ updateCircuitDisplay();
+};
+
+// __display(host, port, password)__.
+// The main function for activating automatic display of the Tor circuit.
+// A reference to this function (called runTorCircuitDisplay) is exported as a global.
+let display = function (host, port, password) {
+ let myController = controller(host, port || 9151, password, function (x) { logger.eclog(5, x); });
+ syncDisplayWithSelectedTab();
+ collectBuiltCircuitData(myController);
+};
+
+return display;
+
+// Finish runTorCircuitDisplay()
+})();
+
diff --git a/src/chrome/content/torbutton.js b/src/chrome/content/torbutton.js
index 7fddf07..5be2c6d 100644
--- a/src/chrome/content/torbutton.js
+++ b/src/chrome/content/torbutton.js
@@ -578,6 +578,8 @@ function torbutton_init() {
torbutton_update_statusbar(mode);
torbutton_notify_if_update_needed();
+ runTorCircuitDisplay(m_tb_control_host, m_tb_control_port, m_tb_control_pass);
+
torbutton_log(3, 'init completed');
}
diff --git a/src/chrome/content/torbutton.xul b/src/chrome/content/torbutton.xul
index 9e10b09..00dc6f0 100644
--- a/src/chrome/content/torbutton.xul
+++ b/src/chrome/content/torbutton.xul
@@ -11,6 +11,7 @@
<script src="chrome://torbutton/content/stanford-safecache.js" />
<script type="application/x-javascript" src="chrome://torbutton/content/torbutton_util.js" />
+ <script type="application/x-javascript" src="chrome://torbutton/content/tor-circuit-display.js" />
<script type="application/x-javascript" src="chrome://torbutton/content/torbutton.js" />
<script language="JavaScript">
//onLoad Hander
diff --git a/src/chrome/skin/torbutton.css b/src/chrome/skin/torbutton.css
index ef8abbc..f368c9c 100644
--- a/src/chrome/skin/torbutton.css
+++ b/src/chrome/skin/torbutton.css
@@ -104,3 +104,18 @@ statusbarpanel#plugins-status[status="0"] {
#torbutton-downloadUpdate {
font-weight: bold;
}
+
+svg.circuit text {
+ font-family: Arial;
+}
+
+svg#tor-circuit text.node-text {
+ dominant-baseline: central;
+ font-size: 14px;
+}
+
+svg#tor-circuit circle.node-circle {
+ stroke: #195021;
+ stroke-width: 2px;
+ fill: white;
+}
\ No newline at end of file
diff --git a/src/modules/tor-control-port.js b/src/modules/tor-control-port.js
new file mode 100644
index 0000000..2f993d7
--- /dev/null
+++ b/src/modules/tor-control-port.js
@@ -0,0 +1,575 @@
+// A module for TorBrowser that provides an asynchronous controller for
+// Tor, through its ControlPort.
+//
+// This file is written in call stack order (later functions
+// call earlier functions). The file can be processed
+// with docco.js to produce pretty documentation.
+//
+// To import the module, use
+//
+// let { controller } = Components.utils.import("path/to/controlPort.jsm");
+//
+// See the last function defined in this file, controller(host, port, password, onError)
+// for usage of the controller function.
+
+/* jshint esnext: true */
+/* jshint -W097 */
+/* global Components, console */
+"use strict";
+
+// ### Mozilla Abbreviations
+let {classes: Cc, interfaces: Ci, results: Cr, Constructor: CC, utils: Cu } = Components;
+
+// ## io
+// I/O utilities namespace
+let io = io || {};
+
+// __io.asyncSocketStreams(host, port)__.
+// Creates a pair of asynchronous input and output streams for a socket at the
+// given host and port.
+io.asyncSocketStreams = function (host, port) {
+ let socketTransportService = Cc["@mozilla.org/network/socket-transport-service;1"]
+ .getService(Components.interfaces.nsISocketTransportService),
+ BLOCKING = Ci.nsITransport.OPEN_BLOCKING,
+ UNBUFFERED = Ci.nsITransport.OPEN_UNBUFFERED,
+ // Create an instance of a socket transport.
+ socketTransport = socketTransportService.createTransport(null, 0, host, port, null),
+ // Open unbuffered synchronous outputStream.
+ outputStream = socketTransport.openOutputStream(BLOCKING | UNBUFFERED, 1, 1),
+ // Open unbuffered asynchronous inputStream.
+ inputStream = socketTransport.openInputStream(UNBUFFERED, 1, 1)
+ .QueryInterface(Ci.nsIAsyncInputStream);
+ return [inputStream, outputStream];
+};
+
+// __io.pumpInputStream(scriptableInputStream, onInputData, onError)__.
+// Run an "input stream pump" that takes an input stream and
+// asynchronously pumps incoming data to the onInputData callback.
+io.pumpInputStream = function (inputStream, onInputData, onError) {
+ // Wrap raw inputStream with a "ScriptableInputStream" so we can read incoming data.
+ let ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1",
+ "nsIScriptableInputStream", "init"),
+ scriptableInputStream = new ScriptableInputStream(inputStream),
+ // A private method to read all data available on the input stream.
+ readAll = function() {
+ return scriptableInputStream.read(scriptableInputStream.available());
+ },
+ pump = Cc["@mozilla.org/network/input-stream-pump;1"]
+ .createInstance(Components.interfaces.nsIInputStreamPump);
+ // Start the pump.
+ pump.init(inputStream, -1, -1, 0, 0, true);
+ // Tell the pump to read all data whenever it is available, and pass the data
+ // to the onInputData callback. The first argument to asyncRead implements
+ // nsIStreamListener.
+ pump.asyncRead({ onStartRequest: function (request, context) { },
+ onStopRequest: function (request, context, code) { },
+ onDataAvailable : function (request, context, stream, offset, count) {
+ try {
+ onInputData(readAll());
+ } catch (error) {
+ // readAll() or onInputData(...) has thrown an error.
+ // Notify calling code through onError.
+ onError(error);
+ }
+ } }, null);
+};
+
+// __io.asyncSocket(host, port, onInputData, onError)__.
+// Creates an asynchronous, text-oriented TCP socket at host:port.
+// The onInputData callback should accept a single argument, which will be called
+// repeatedly, whenever incoming text arrives. Returns a socket object with two methods:
+// socket.write(text) and socket.close(). onError will be passed the error object
+// whenever a write fails.
+io.asyncSocket = function (host, port, onInputData, onError) {
+ let [inputStream, outputStream] = io.asyncSocketStreams(host, port);
+ // Run an input stream pump to send incoming data to the onInputData callback.
+ io.pumpInputStream(inputStream, onInputData, onError);
+ return {
+ // Write a message to the socket.
+ write : function(aString) {
+ try {
+ outputStream.write(aString, aString.length);
+ // console.log(aString);
+ } catch (err) {
+ // This write() method is not necessarily called by a callback,
+ // but we pass any thrown errors to onError to ensure the socket
+ // error handling uses a consistent single path.
+ onError(err);
+ }
+ },
+ // Close the socket.
+ close : function () {
+ // Close stream objects.
+ inputStream.close();
+ outputStream.close();
+ }
+ };
+};
+
+// __io.onDataFromOnLine(onLine)__.
+// Converts a callback that expects incoming individual lines of text to a callback that
+// expects incoming raw socket string data.
+io.onDataFromOnLine = function (onLine) {
+ // A private variable that stores the last unfinished line.
+ let pendingData = "";
+ // Return a callback to be passed to io.asyncSocket. First, splits data into lines of
+ // text. If the incoming data is not terminated by CRLF, then the last
+ // unfinished line will be stored in pendingData, to be prepended to the data in the
+ // next call to onData. The already complete lines of text are then passed in sequence
+ // to onLine.
+ return function (data) {
+ let totalData = pendingData + data,
+ lines = totalData.split("\r\n"),
+ n = lines.length;
+ pendingData = lines[n - 1];
+ // Call onLine for all completed lines.
+ lines.slice(0,-1).map(onLine);
+ };
+};
+
+// __io.onLineFromOnMessage(onMessage)__.
+// Converts a callback that expects incoming control port multiline message strings to a
+// callback that expects individual lines.
+io.onLineFromOnMessage = function (onMessage) {
+ // A private variable that stores the last unfinished line.
+ let pendingLines = [];
+ // Return a callback that expects individual lines.
+ return function (line) {
+ // Add to the list of pending lines.
+ pendingLines.push(line);
+ // If line is the last in a message, then pass on the full multiline message.
+ if (line.match(/^\d\d\d /) && (pendingLines.length == 1 ||
+ pendingLines[0].startsWith(line.substring(0,3)))) {
+ // Combine pending lines to form message.
+ let message = pendingLines.join("\r\n");
+ // Wipe pendingLines before we call onMessage, in case onMessage throws an error.
+ pendingLines = [];
+ // Pass multiline message to onMessage.
+ onMessage(message);
+ // console.log(message);
+ }
+ };
+};
+
+// __io.callbackDispatcher()__.
+// Returns [onString, dispatcher] where the latter is an object with two member functions:
+// dispatcher.addCallback(regex, callback), and dispatcher.removeCallback(callback).
+// Pass onString to another function that needs a callback with a single string argument.
+// Whenever dispatcher.onString receives a string, the dispatcher will check for any
+// regex matches and pass the string on to the corresponding callback(s).
+io.callbackDispatcher = function () {
+ let callbackPairs = [],
+ removeCallback = function (aCallback) {
+ callbackPairs = callbackPairs.filter(function ([regex, callback]) {
+ return callback !== aCallback;
+ });
+ },
+ addCallback = function (regex, callback) {
+ if (callback) {
+ callbackPairs.push([regex, callback]);
+ }
+ return function () { removeCallback(callback); };
+ },
+ onString = function (message) {
+ for (let [regex, callback] of callbackPairs) {
+ if (message.match(regex)) {
+ callback(message);
+ }
+ }
+ };
+ return [onString, {addCallback : addCallback, removeCallback : removeCallback}];
+};
+
+// __io.matchRepliesToCommands(asyncSend)__.
+// Takes asyncSend(message), an asynchronous send function, and returns two functions
+// sendCommand(command, replyCallback) and onReply(response). If we call sendCommand,
+// then when onReply is called, the corresponding replyCallback will be called.
+io.matchRepliesToCommands = function (asyncSend) {
+ let commandQueue = [],
+ sendCommand = function (command, replyCallback) {
+ commandQueue.push([command, replyCallback]);
+ asyncSend(command);
+ },
+ onReply = function (reply) {
+ let [command, replyCallback] = commandQueue.shift();
+ if (replyCallback) { replyCallback(reply); }
+ },
+ onFailure = function () {
+ commandQueue.shift();
+ };
+ return [sendCommand, onReply, onFailure];
+};
+
+// __io.controlSocket(host, port, password, onError)__.
+// Instantiates and returns a socket to a tor ControlPort at host:port,
+// authenticating with the given password. onError is called with an
+// error object as its single argument whenever an error occurs. Example:
+//
+// // Open the socket
+// let socket = controlSocket("127.0.0.1", 9151, "MyPassw0rd",
+// function (error) { console.log(error.message || error); });
+// // Send command and receive "250" reply or error message
+// socket.sendCommand(commandText, replyCallback);
+// // Register or deregister for "650" notifications
+// // that match regex
+// socket.addNotificationCallback(regex, callback);
+// socket.removeNotificationCallback(callback);
+// // Close the socket permanently
+// socket.close();
+io.controlSocket = function (host, port, password, onError) {
+ // Produce a callback dispatcher for Tor messages.
+ let [onMessage, mainDispatcher] = io.callbackDispatcher(),
+ // Open the socket and convert format to Tor messages.
+ socket = io.asyncSocket(host, port,
+ io.onDataFromOnLine(io.onLineFromOnMessage(onMessage)),
+ onError),
+ // Tor expects any commands to be terminated by CRLF.
+ writeLine = function (text) { socket.write(text + "\r\n"); },
+ // Ensure we return the correct reply for each sendCommand.
+ [sendCommand, onReply, onFailure] = io.matchRepliesToCommands(writeLine),
+ // Create a secondary callback dispatcher for Tor notification messages.
+ [onNotification, notificationDispatcher] = io.callbackDispatcher();
+ // Pass successful reply back to sendCommand callback.
+ mainDispatcher.addCallback(/^2\d\d/, onReply);
+ // Pass error message to sendCommand callback.
+ mainDispatcher.addCallback(/^[45]\d\d/, function (message) {
+ onFailure();
+ onError(new Error(message));
+ });
+ // Pass asynchronous notifications to notification dispatcher.
+ mainDispatcher.addCallback(/^650/, onNotification);
+ // Log in to control port.
+ sendCommand("authenticate " + (password || ""));
+ // Activate needed events.
+ sendCommand("setevents stream circ");
+ return { close : socket.close, sendCommand : sendCommand,
+ addNotificationCallback : notificationDispatcher.addCallback,
+ removeNotificationCallback : notificationDispatcher.removeCallback };
+};
+
+// ## utils
+// A namespace for utility functions
+let utils = utils || {};
+
+// __utils.identity(x)__.
+// Returns its argument unchanged.
+utils.identity = function (x) { return x; };
+
+// __utils.isString(x)__.
+// Returns true iff x is a string.
+utils.isString = function (x) {
+ return typeof(x) === 'string' || x instanceof String;
+};
+
+// __utils.capture(string, regex)__.
+// Takes a string and returns an array of capture items, where regex must have a single
+// capturing group and use the suffix /.../g to specify a global search.
+utils.capture = function (string, regex) {
+ let matches = [];
+ // Special trick to use string.replace for capturing multiple matches.
+ string.replace(regex, function (a, captured) {
+ matches.push(captured);
+ });
+ return matches;
+};
+
+// __utils.extractor(regex)__.
+// Returns a function that takes a string and returns an array of regex matches. The
+// regex must use the suffix /.../g to specify a global search.
+utils.extractor = function (regex) {
+ return function (text) {
+ return utils.capture(text, regex);
+ };
+};
+
+// __utils.splitLines(string)__.
+// Splits a string into an array of strings, each corresponding to a line.
+utils.splitLines = function (string) { return string.split(/\r?\n/); };
+
+// __utils.splitAtSpaces(string)__.
+// Splits a string into chunks between spaces. Does not split at spaces
+// inside pairs of quotation marks.
+utils.splitAtSpaces = utils.extractor(/((\S*?"(.*?)")+\S*|\S+)/g);
+
+// __utils.splitAtEquals(string)__.
+// Splits a string into chunks between equals. Does not split at equals
+// inside pairs of quotation marks.
+utils.splitAtEquals = utils.extractor(/(([^=]*?"(.*?)")+[^=]*|[^=]+)/g);
+
+// __utils.mergeObjects(arrayOfObjects)__.
+// Takes an array of objects like [{"a":"b"},{"c":"d"}] and merges to a single object.
+// Pure function.
+utils.mergeObjects = function (arrayOfObjects) {
+ let result = {};
+ for (let obj of arrayOfObjects) {
+ for (var key in obj) {
+ result[key] = obj[key];
+ }
+ }
+ return result;
+};
+
+// __utils.listMapData(parameterString, listNames)__.
+// Takes a list of parameters separated by spaces, of which the first several are
+// unnamed, and the remainder are named, in the form `NAME=VALUE`. Apply listNames
+// to the unnamed parameters, and combine them in a map with the named parameters.
+// Example: `40 FAILED 0 95.78.59.36:80 REASON=CANT_ATTACH`
+//
+// utils.listMapData("40 FAILED 0 95.78.59.36:80 REASON=CANT_ATTACH",
+// ["streamID", "event", "circuitID", "IP"])
+// // --> {"streamID" : "40", "event" : "FAILED", "circuitID" : "0",
+// // "address" : "95.78.59.36:80", "REASON" : "CANT_ATTACH"}"
+utils.listMapData = function (parameterString, listNames) {
+ // Split out the space-delimited parameters.
+ let parameters = utils.splitAtSpaces(parameterString),
+ dataMap = {};
+ // Assign listNames to the first n = listNames.length parameters.
+ for (let i = 0; i < listNames.length; ++i) {
+ dataMap[listNames[i]] = parameters[i];
+ }
+ // Read key-value pairs and copy these to the dataMap.
+ for (let i = listNames.length; i < parameters.length; ++i) {
+ let [key, value] = utils.splitAtEquals(parameters[i]);
+ if (key && value) {
+ dataMap[key] = value;
+ }
+ }
+ return dataMap;
+};
+
+// ## info
+// A namespace for functions related to tor's GETINFO command.
+let info = info || {};
+
+// __info.keyValueStringsFromMessage(messageText)__.
+// Takes a message (text) response to GETINFO and provides a series of key-value
+// strings, which are either multiline (with a `250+` prefix):
+//
+// 250+config/defaults=
+// AccountingMax "0 bytes"
+// AllowDotExit "0"
+// .
+//
+// or single-line (with a `250-` prefix):
+//
+// 250-version=0.2.6.0-alpha-dev (git-b408125288ad6943)
+info.keyValueStringsFromMessage = utils.extractor(/^(250\+[\s\S]+?^\.|250-.+?)$/gmi);
+
+// __info.applyPerLine(transformFunction)__.
+// Returns a function that splits text into lines,
+// and applies transformFunction to each line.
+info.applyPerLine = function (transformFunction) {
+ return function (text) {
+ return utils.splitLines(text.trim()).map(transformFunction);
+ };
+};
+
+// __info.routerStatusParser(valueString)__.
+// Parses a router status entry as, described in
+// https://gitweb.torproject.org/torspec.git/blob/HEAD:/dir-spec.txt
+// (search for "router status entry")
+info.routerStatusParser = function (valueString) {
+ let lines = utils.splitLines(valueString),
+ objects = [];
+ for (let line of lines) {
+ // Drop first character and grab data following it.
+ let myData = line.substring(2),
+ // Accumulate more maps with data, depending on the first character in the line.
+ dataFun = {
+ "r" : data => utils.listMapData(data, ["nickname", "identity", "digest",
+ "publicationDate", "publicationTime",
+ "IP", "ORPort", "DirPort"]) ,
+ "a" : data => ({ "IPv6" : data }) ,
+ "s" : data => ({ "statusFlags" : utils.splitAtSpaces(data) }) ,
+ "v" : data => ({ "version" : data }) ,
+ "w" : data => utils.listMapData(data, []) ,
+ "p" : data => ({ "portList" : data.split(",") }) ,
+ "m" : data => utils.listMapData(data, [])
+ }[line.charAt(0)];
+ if (dataFun !== undefined) {
+ objects.push(dataFun(myData));
+ }
+ }
+ return utils.mergeObjects(objects);
+};
+
+// __info.circuitStatusParser(line)__.
+// Parse the output of a circuit status line.
+info.circuitStatusParser = function (line) {
+ let data = utils.listMapData(line, ["id","status","circuit"]),
+ circuit = data.circuit;
+ // Parse out the individual circuit IDs and names.
+ if (circuit) {
+ data.circuit = circuit.split(",").map(function (x) {
+ return x.split(/~|=/);
+ });
+ }
+ return data;
+};
+
+// __info.streamStatusParser(line)__.
+// Parse the output of a stream status line.
+info.streamStatusParser = function (text) {
+ return utils.listMapData(text, ["StreamID", "StreamStatus",
+ "CircuitID", "Target"]);
+};
+
+// __info.parsers__.
+// A map of GETINFO keys to parsing function, which convert result strings to JavaScript
+// data.
+info.parsers = {
+ "version" : utils.identity,
+ "config-file" : utils.identity,
+ "config-defaults-file" : utils.identity,
+ "config-text" : utils.identity,
+ "ns/id/" : info.routerStatusParser,
+ "ns/name/" : info.routerStatusParser,
+ "ip-to-country/" : utils.identity,
+ "circuit-status" : info.applyPerLine(info.circuitStatusParser),
+ "stream-status" : info.applyPerLine(info.streamStatusParser)
+};
+
+// __info.getParser(key)__.
+// Takes a key and determines the parser function that should be used to
+// convert its corresponding valueString to JavaScript data.
+info.getParser = function(key) {
+ return info.parsers[key] ||
+ info.parsers[key.substring(0, key.lastIndexOf("/") + 1)] ||
+ "unknown";
+};
+
+// __info.stringToValue(string)__.
+// Converts a key-value string as from GETINFO to a value.
+info.stringToValue = function (string) {
+ // key should look something like `250+circuit-status=` or `250-circuit-status=...`
+ let key = string.match(/^250[\+-](.+?)=/mi)[1],
+ // matchResult finds a single-line result for `250-` or a multi-line one for `250+`.
+ matchResult = string.match(/250\-.+?=(.*?)$/mi) ||
+ string.match(/250\+.+?=([\s\S]*?)^\.$/mi),
+ // Retrieve the captured group (the text of the value in the key-value pair)
+ valueString = matchResult ? matchResult[1] : null;
+ // Return value where the latter has been parsed according to the key requested.
+ return info.getParser(key)(valueString);
+};
+
+// __info.getInfoMultiple(aControlSocket, keys, onData)__.
+// Sends GETINFO for an array of keys. Passes onData an array of their respective results,
+// in order.
+info.getInfoMultiple = function (aControlSocket, keys, onData) {
+ /*
+ if (!(keys instanceof Array)) {
+ throw new Error("keys argument should be an array");
+ }
+ if (!(onData instanceof Function)) {
+ throw new Error("onData argument should be a function");
+ }
+ let parsers = keys.map(info.getParser);
+ if (parsers.indexOf("unknown") !== -1) {
+ throw new Error("unknown key");
+ }
+ if (parsers.indexOf("not supported") !== -1) {
+ throw new Error("unsupported key");
+ }
+ */
+ aControlSocket.sendCommand("getinfo " + keys.join(" "), function (message) {
+ onData(info.keyValueStringsFromMessage(message).map(info.stringToValue));
+ });
+};
+
+// __info.getInfo(controlSocket, key, onValue)__.
+// Sends GETINFO for a single key. Passes onValue the value for that key.
+info.getInfo = function (aControlSocket, key, onValue) {
+ /*
+ if (!utils.isString(key)) {
+ throw new Error("key argument should be a string");
+ }
+ if (!(onValue instanceof Function)) {
+ throw new Error("onValue argument should be a function");
+ }
+ */
+ info.getInfoMultiple(aControlSocket, [key], function (data) {
+ onValue(data[0]);
+ });
+};
+
+// ## event
+// Handlers for events
+
+let event = event || {};
+
+// __event.parsers__.
+// A map of EVENT keys to parsing functions, which convert result strings to JavaScript
+// data.
+event.parsers = {
+ "stream" : info.streamStatusParser,
+ "circ" : info.circuitStatusParser
+};
+
+// __event.messageToData(type, message)__.
+// Extract the data from an event.
+event.messageToData = function (type, message) {
+ let dataText = message.match(/^650 \S+?\s(.*?)$/mi)[1];
+ return dataText ? event.parsers[type.toLowerCase()](dataText) : null;
+};
+
+// __event.watchEvent(controlSocket, type, filter, onData)__.
+// Watches for a particular type of event. If filter(data) returns true, the event's
+// data is pass to the onData callback.
+event.watchEvent = function (controlSocket, type, filter, onData) {
+ controlSocket.addNotificationCallback(new RegExp("^650." + type, "i"),
+ function (message) {
+ let data = event.messageToData(type, message);
+ if (filter === null || filter(data)) {
+ onData(data);
+ }
+ });
+};
+
+// ## tor
+// Things related to the main controller.
+let tor = tor || {};
+
+// __tor.controller(host, port, password, onError)__.
+// Creates a tor controller at the given host and port, with the given password.
+// onError returns asynchronously whenever a connection error occurs.
+tor.controller = function (host, port, password, onError) {
+ let socket = io.controlSocket(host, port, password, onError);
+ return { getInfo : function (key, log) { info.getInfo(socket, key, log); } ,
+ getInfoMultiple : function (keys, log) {
+ info.getInfoMultiple(socket, keys, log);
+ },
+ watchEvent : function (type, filter, onData) {
+ event.watchEvent(socket, type, filter, onData);
+ },
+ close : socket.close };
+};
+
+// __tor.controllerCache__.
+// A map from "host:port" to controller objects. Prevents redundant instantiation
+// of control sockets.
+tor.controllerCache = {};
+
+// ## Export
+
+// __controller(host, port, password, onError)__.
+// Instantiates and returns a controller object connected to a tor ControlPort
+// at host:port, authenticating with the given password, if the controller doesn't yet
+// exist. Otherwise returns the existing controller to the given host:port.
+// onError is called with an error object as its single argument whenever
+// an error occurs. Example:
+//
+// // Get the controller
+// let c = controller("127.0.0.1", 9151, "MyPassw0rd",
+// function (error) { console.log(error.message || error); });
+// // Send command and receive `250` reply or error message
+// c.getInfo("ip-to-country/16.16.16.16", console.log);
+// // Close the controller permanently
+// c.close();
+let controller = function (host, port, password, onError) {
+ let dest = host + ":" + port;
+ return (tor.controllerCache[dest] = tor.controllerCache[dest] ||
+ tor.controller(host, port, password, onError));
+};
+
+// Export the controller function for external use.
+var EXPORTED_SYMBOLS = ["controller"];
1
0

[torbutton/master] Bug #3455.3: Add DomainIsolator, for isolating circuit by domain.
by mikeperry@torproject.org 30 Oct '14
by mikeperry@torproject.org 30 Oct '14
30 Oct '14
commit 59445b7baed58e712bd38c02e6dc75882ff0c997
Author: Arthur Edelstein <arthuredelstein(a)gmail.com>
Date: Mon Jul 14 00:40:13 2014 -0700
Bug #3455.3: Add DomainIsolator, for isolating circuit by domain.
An XPCOM component that registers a ProtocolProxyChannelFilter
which sets the username/password for each web request according to
url bar domain.
---
src/chrome.manifest | 5 +-
src/components/domain-isolator.js | 128 +++++++++++++++++++++++++++++++++++++
2 files changed, 132 insertions(+), 1 deletion(-)
diff --git a/src/chrome.manifest b/src/chrome.manifest
index af44862..d211984 100644
--- a/src/chrome.manifest
+++ b/src/chrome.manifest
@@ -155,7 +155,10 @@ contract @torproject.org/torbutton-torCheckService;1 {5d57312b-5d8c-4169-b4af-e8
component {f36d72c9-9718-4134-b550-e109638331d7} components/torbutton-logger.js
contract @torproject.org/torbutton-logger;1 {f36d72c9-9718-4134-b550-e109638331d7}
+component {e33fd6d4-270f-475f-a96f-ff3140279f68} components/domain-isolator.js
+contract @torproject.org/domain-isolator;1 {e33fd6d4-270f-475f-a96f-ff3140279f68}
+
category profile-after-change CookieJarSelector @torproject.org/cookie-jar-selector;1
-# category profile-after-change RefSpoofer @torproject.org/torRefSpoofer;1
category profile-after-change TBSessionBlocker @torproject.org/torbutton-ss-blocker;1
category profile-after-change StartupObserver @torproject.org/startup-observer;1
+category profile-after-change DomainIsolator @torproject.org/domain-isolator;1
\ No newline at end of file
diff --git a/src/components/domain-isolator.js b/src/components/domain-isolator.js
new file mode 100644
index 0000000..e8e6bfa
--- /dev/null
+++ b/src/components/domain-isolator.js
@@ -0,0 +1,128 @@
+// # domain-isolator.js
+// A component for TorBrowser that puts requests from different
+// first party domains on separate tor circuits.
+
+// This file is written in call stack order (later functions
+// call earlier functions). The code file can be processed
+// with docco.js to provide clear documentation.
+
+/* jshint moz: true */
+/* global Components, console, XPCOMUtils */
+
+// ### Abbreviations
+const Cc = Components.classes, Ci = Components.interfaces, Cu = Components.utils;
+
+// Make the logger available.
+let logger = Cc["@torproject.org/torbutton-logger;1"]
+ .getService(Components.interfaces.nsISupports).wrappedJSObject;
+
+// ## mozilla namespace.
+// Useful functionality for interacting with Mozilla services.
+let mozilla = mozilla || {};
+
+// __mozilla.protocolProxyService__.
+// Mozilla's protocol proxy service, useful for managing proxy connections made
+// by the browser.
+mozilla.protocolProxyService = Cc["@mozilla.org/network/protocol-proxy-service;1"]
+ .getService(Ci.nsIProtocolProxyService);
+
+// __mozilla.thirdPartyUtil__.
+// Mozilla's Thirdy Party Utilities, for figuring out first party domain.
+mozilla.thirdPartyUtil = Cc["@mozilla.org/thirdpartyutil;1"]
+ .getService(Ci.mozIThirdPartyUtil);
+
+// __mozilla.registerProxyChannelFilter(filterFunction, positionIndex)__.
+// Registers a proxy channel filter with the Mozilla Protocol Proxy Service,
+// which will help to decide the proxy to be used for a given channel.
+// The filterFunction should expect two arguments, (aChannel, aProxy),
+// where aProxy is the proxy or list of proxies that would be used by default
+// for the given channel, and should return a new Proxy or list of Proxies.
+mozilla.registerProxyChannelFilter = function (filterFunction, positionIndex) {
+ let proxyFilter = {
+ applyFilter : function (aProxyService, aChannel, aProxy) {
+ return filterFunction(aChannel, aProxy);
+ }
+ };
+ mozilla.protocolProxyService.registerChannelFilter(proxyFilter, positionIndex);
+};
+
+// ## tor functionality.
+let tor = tor || {};
+
+// __tor.noncesForDomains__.
+// A mutable map that records what nonce we are using for each domain.
+tor.noncesForDomains = {};
+
+// __tor.socksProxyCredentials(originalProxy, domain)__.
+// Takes a proxyInfo object (originalProxy) and returns a new proxyInfo
+// object with the same properties, except the username is set to the
+// the domain, and the password is a nonce.
+tor.socksProxyCredentials = function (originalProxy, domain) {
+ // Check if we already have a nonce. If not, create
+ // one for this domain.
+ if (!tor.noncesForDomains.hasOwnProperty(domain)) {
+ tor.noncesForDomains[domain] = 0;
+ }
+ let proxy = originalProxy.QueryInterface(Ci.nsIProxyInfo);
+ return mozilla.protocolProxyService
+ .newSOCKSProxyInfo(proxy.host,
+ proxy.port,
+ domain, // username
+ tor.noncesForDomains[domain].toString(), // password
+ proxy.flags,
+ proxy.failoverTimeout,
+ proxy.failoverProxy);
+};
+
+// __tor.isolateCircuitsByDomain()__.
+// For every HTTPChannel, replaces the default SOCKS proxy with one that authenticates
+// to the SOCKS server (the tor client process) with a username (the first party domain)
+// and a nonce password. Tor provides a separate circuit for each username+password
+// combination.
+tor.isolateCircuitsByDomain = function () {
+ mozilla.registerProxyChannelFilter(function (aChannel, aProxy) {
+ try {
+ let channel = aChannel.QueryInterface(Ci.nsIHttpChannel),
+ firstPartyURI = mozilla.thirdPartyUtil.getFirstPartyURIFromChannel(channel, true)
+ .QueryInterface(Ci.nsIURI),
+ firstPartyDomain = mozilla.thirdPartyUtil
+ .getFirstPartyHostForIsolation(firstPartyURI),
+ proxy = aProxy.QueryInterface(Ci.nsIProxyInfo),
+ replacementProxy = tor.socksProxyCredentials(aProxy, firstPartyDomain);
+ logger.eclog(3, "tor SOCKS: " + channel.URI.spec + " via " +
+ replacementProxy.username + ":" + replacementProxy.password);
+ return replacementProxy;
+ } catch (err) {
+ // If we fail, then just use the default proxyInfo.
+ return aProxy;
+ }
+ }, 0);
+};
+
+// ## XPCOM component construction.
+// Module specific constants
+const kMODULE_NAME = "TorBrowser Domain Isolator";
+const kMODULE_CONTRACTID = "@torproject.org/domain-isolator;1";
+const kMODULE_CID = Components.ID("e33fd6d4-270f-475f-a96f-ff3140279f68");
+
+// Import XPCOMUtils object.
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+// DomainIsolator object. Constructor does nothing.
+function DomainIsolator() { }
+// Firefox component requirements
+DomainIsolator.prototype = {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, Ci.nsIObserver]),
+ classDescription: kMODULE_NAME,
+ classID: kMODULE_CID,
+ contractID: kMODULE_CONTRACTID,
+ observe: function (subject, topic, data) {
+ if (topic === "profile-after-change") {
+ logger.eclog(3, "domain isolator: set up isolating circuits by domain");
+ tor.isolateCircuitsByDomain();
+ }
+ }
+};
+
+// Assign factory to global object.
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([DomainIsolator]);
1
0