[tor-commits] [translation/tails-iuk_completed] Update translations for tails-iuk_completed
commit b0b8fd65216031ee04925201b934b42c5dd32011 Author: Translation commit bot Date: Thu Jun 25 12:46:42 2015 + Update translations for tails-iuk_completed --- id.po |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/id.po b/id.po index 1f692e9..8e2f70b 100644 --- a/id.po +++ b/id.po @@ -12,7 +12,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: Tails developers \n" "POT-Creation-Date: 2015-05-02 21:08+0200\n" -"PO-Revision-Date: 2015-06-22 15:36+\n" +"PO-Revision-Date: 2015-06-25 12:38+\n" "Last-Translator: Zamani Karmana \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/torproject/language/id/)\n" "MIME-Version: 1.0\n" @@ -122,7 +122,7 @@ msgstr "Mutakhirkan sekarang" #: ../lib/Tails/IUK/Frontend.pm:387 msgid "Upgrade later" -msgstr "mutakhirkan nanti" +msgstr "Mutakhirkan nanti" #: ../lib/Tails/IUK/Frontend.pm:395 #, perl-brace-format ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/tails-misc] Update translations for tails-misc
commit 2475aaf13e7b6955e671bea070846afc12313efc Author: Translation commit bot Date: Thu Jun 25 12:46:13 2015 + Update translations for tails-misc --- id.po |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/id.po b/id.po index 60d2741..791ad63 100644 --- a/id.po +++ b/id.po @@ -14,7 +14,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-05-02 23:47+0200\n" -"PO-Revision-Date: 2015-06-22 15:36+\n" +"PO-Revision-Date: 2015-06-25 12:37+\n" "Last-Translator: Zamani Karmana \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/torproject/language/id/)\n" "MIME-Version: 1.0\n" @@ -117,7 +117,7 @@ msgstr "Kepercayaan Tidak Dikenal" #: config/chroot_local-includes/usr/local/bin/gpgApplet:309 msgid "Marginal Trust" -msgstr "Kepercayaan Rendah" +msgstr "Kepercayaan Marginal" #: config/chroot_local-includes/usr/local/bin/gpgApplet:311 msgid "Full Trust" ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/abouttor-homepage_completed] Update translations for abouttor-homepage_completed
commit 62be299d0ed74cad0d72ad1c4e55c7387238 Author: Translation commit bot Date: Thu Jun 25 12:46:25 2015 + Update translations for abouttor-homepage_completed --- de/aboutTor.dtd|2 +- pt_BR/aboutTor.dtd |2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/de/aboutTor.dtd b/de/aboutTor.dtd index 67e04ad..955ac10 100644 --- a/de/aboutTor.dtd +++ b/de/aboutTor.dtd @@ -25,7 +25,7 @@ https://startpage.com/rth/search";> https://duckduckgo.com/html/";> -https://search.disconnect.me/searchTerms/search?ses=Google&location_option=DE";> +https://search.disconnect.me/searchTerms/search?ses=Google&location_option=DE&source=tor";> diff --git a/pt_BR/aboutTor.dtd b/pt_BR/aboutTor.dtd index e9713d4..d118bae 100644 --- a/pt_BR/aboutTor.dtd +++ b/pt_BR/aboutTor.dtd @@ -25,7 +25,7 @@ https://startpage.com/rth/search";> https://duckduckgo.com/html/";> -https://search.disconnect.me/searchTerms/search?ses=Google&location_option=BR";> +https://search.disconnect.me/searchTerms/search?ses=Google&location_option=US&source=tor";> ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/tails-misc_completed] Update translations for tails-misc_completed
commit 39e0775d173897b4b184bf34a467a802fed1950b Author: Translation commit bot Date: Thu Jun 25 12:46:17 2015 + Update translations for tails-misc_completed --- id.po |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/id.po b/id.po index 60d2741..791ad63 100644 --- a/id.po +++ b/id.po @@ -14,7 +14,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-05-02 23:47+0200\n" -"PO-Revision-Date: 2015-06-22 15:36+\n" +"PO-Revision-Date: 2015-06-25 12:37+\n" "Last-Translator: Zamani Karmana \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/torproject/language/id/)\n" "MIME-Version: 1.0\n" @@ -117,7 +117,7 @@ msgstr "Kepercayaan Tidak Dikenal" #: config/chroot_local-includes/usr/local/bin/gpgApplet:309 msgid "Marginal Trust" -msgstr "Kepercayaan Rendah" +msgstr "Kepercayaan Marginal" #: config/chroot_local-includes/usr/local/bin/gpgApplet:311 msgid "Full Trust" ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/tor-launcher-network-settings] Update translations for tor-launcher-network-settings
commit 5f9c5409864732a504b9a35df942dc0ed34a5d5e Author: Translation commit bot Date: Thu Jun 25 12:46:05 2015 + Update translations for tor-launcher-network-settings --- id/network-settings.dtd |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/id/network-settings.dtd b/id/network-settings.dtd index b992517..4673dee 100644 --- a/id/network-settings.dtd +++ b/id/network-settings.dtd @@ -23,7 +23,7 @@ - + ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/abouttor-homepage] Update translations for abouttor-homepage
commit 01140590be6ff41d67f801e65f26301f31e9e2b9 Author: Translation commit bot Date: Thu Jun 25 12:46:22 2015 + Update translations for abouttor-homepage --- de/aboutTor.dtd |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/de/aboutTor.dtd b/de/aboutTor.dtd index 68dcc78..955ac10 100644 --- a/de/aboutTor.dtd +++ b/de/aboutTor.dtd @@ -25,7 +25,7 @@ https://startpage.com/rth/search";> https://duckduckgo.com/html/";> -https://search.disconnect.me/searchTerms/search?ses=Google&location_option=US&source=tor";> +https://search.disconnect.me/searchTerms/search?ses=Google&location_option=DE&source=tor";> ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/tor-launcher-network-settings_completed] Update translations for tor-launcher-network-settings_completed
commit a657ba10b30c87bf71e9e3ca9e0471f40c11942c Author: Translation commit bot Date: Thu Jun 25 12:46:09 2015 + Update translations for tor-launcher-network-settings_completed --- id/network-settings.dtd |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/id/network-settings.dtd b/id/network-settings.dtd index b992517..4673dee 100644 --- a/id/network-settings.dtd +++ b/id/network-settings.dtd @@ -23,7 +23,7 @@ - + ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/tails-persistence-setup] Update translations for tails-persistence-setup
commit e56436ff5673ea865c1f0475afbeaae9897ae09b Author: Translation commit bot Date: Thu Jun 25 12:45:40 2015 + Update translations for tails-persistence-setup --- id/id.po |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/id/id.po b/id/id.po index d5d463f..d7ddca9 100644 --- a/id/id.po +++ b/id/id.po @@ -15,7 +15,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: Tails developers \n" "POT-Creation-Date: 2015-05-02 21:08+0200\n" -"PO-Revision-Date: 2015-06-22 15:36+\n" +"PO-Revision-Date: 2015-06-25 12:40+\n" "Last-Translator: Zamani Karmana \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/torproject/language/id/)\n" "MIME-Version: 1.0\n" @@ -98,7 +98,7 @@ msgstr "Konfigurasi pencetak" #: ../lib/Tails/Persistence/Configuration/Presets.pm:138 msgid "Bitcoin client" -msgstr "Klien bitcoin" +msgstr "Aplikasi Bitcoin" #: ../lib/Tails/Persistence/Configuration/Presets.pm:140 msgid "Electrum's bitcoin wallet and configuration" ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/mat-gui] Update translations for mat-gui
commit 6a533be80e28373bd55977490f22d2b568eb87d0 Author: Translation commit bot Date: Thu Jun 25 12:45:53 2015 + Update translations for mat-gui --- id.po |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/id.po b/id.po index adf31c9..356f001 100644 --- a/id.po +++ b/id.po @@ -14,7 +14,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-12-31 04:53+0100\n" -"PO-Revision-Date: 2015-06-22 15:37+\n" +"PO-Revision-Date: 2015-06-25 12:38+\n" "Last-Translator: Zamani Karmana \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/torproject/language/id/)\n" "MIME-Version: 1.0\n" @@ -99,7 +99,7 @@ msgstr "Format Berkas Nirbahaya" #: mat-gui:330 msgid "Fileformat not supported" -msgstr "format file tidak didukung" +msgstr "Format berkas tidak didukung" #: mat-gui:333 msgid "These files can not be processed:" ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/mat-gui_completed] Update translations for mat-gui_completed
commit af2d4392eade980bde69da8f8e6559881a0eedb1 Author: Translation commit bot Date: Thu Jun 25 12:45:57 2015 + Update translations for mat-gui_completed --- id.po |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/id.po b/id.po index adf31c9..356f001 100644 --- a/id.po +++ b/id.po @@ -14,7 +14,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-12-31 04:53+0100\n" -"PO-Revision-Date: 2015-06-22 15:37+\n" +"PO-Revision-Date: 2015-06-25 12:38+\n" "Last-Translator: Zamani Karmana \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/torproject/language/id/)\n" "MIME-Version: 1.0\n" @@ -99,7 +99,7 @@ msgstr "Format Berkas Nirbahaya" #: mat-gui:330 msgid "Fileformat not supported" -msgstr "format file tidak didukung" +msgstr "Format berkas tidak didukung" #: mat-gui:333 msgid "These files can not be processed:" ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/tails-persistence-setup_completed] Update translations for tails-persistence-setup_completed
commit 968050b3e8e0eb26daa6b6ff3b9d7575442fb32f Author: Translation commit bot Date: Thu Jun 25 12:45:43 2015 + Update translations for tails-persistence-setup_completed --- id/id.po |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/id/id.po b/id/id.po index d5d463f..d7ddca9 100644 --- a/id/id.po +++ b/id/id.po @@ -15,7 +15,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: Tails developers \n" "POT-Creation-Date: 2015-05-02 21:08+0200\n" -"PO-Revision-Date: 2015-06-22 15:36+\n" +"PO-Revision-Date: 2015-06-25 12:40+\n" "Last-Translator: Zamani Karmana \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/torproject/language/id/)\n" "MIME-Version: 1.0\n" @@ -98,7 +98,7 @@ msgstr "Konfigurasi pencetak" #: ../lib/Tails/Persistence/Configuration/Presets.pm:138 msgid "Bitcoin client" -msgstr "Klien bitcoin" +msgstr "Aplikasi Bitcoin" #: ../lib/Tails/Persistence/Configuration/Presets.pm:140 msgid "Electrum's bitcoin wallet and configuration" ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/https_everywhere] Update translations for https_everywhere
commit 62986b527eb52366d745a3ef5f36cf606839a809 Author: Translation commit bot Date: Thu Jun 25 12:45:23 2015 + Update translations for https_everywhere --- id/https-everywhere.dtd |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/id/https-everywhere.dtd b/id/https-everywhere.dtd index 25969c6..52aa6e7 100644 --- a/id/https-everywhere.dtd +++ b/id/https-everywhere.dtd @@ -19,7 +19,7 @@ - + ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/liveusb-creator_completed] Update translations for liveusb-creator_completed
commit f8da861325b7ce762ec8859f6dee631d62bba1dd Author: Translation commit bot Date: Thu Jun 25 12:45:36 2015 + Update translations for liveusb-creator_completed --- id/id.po |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/id/id.po b/id/id.po index 8741286..b9dbbda 100644 --- a/id/id.po +++ b/id/id.po @@ -14,7 +14,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-05-02 21:10+0200\n" -"PO-Revision-Date: 2015-06-22 15:35+\n" +"PO-Revision-Date: 2015-06-25 12:38+\n" "Last-Translator: Zamani Karmana \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/torproject/language/id/)\n" "MIME-Version: 1.0\n" @@ -136,7 +136,7 @@ msgstr "Membuat %sMB penyimpanan persisten" #: ../liveusb/gui.py:553 msgid "" "Device is not yet mounted, so we cannot determine the amount of free space." -msgstr "Device belum dipasang, jadi kita tidak bisa menentukan jumlah space yang kosong/tersedia" +msgstr "Perangkat belum terkait, sehingga kami tidak bisa memperkirakan sisa ruang kosong yang ada." #: ../liveusb/dialog.py:157 #, python-format ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/gettor] Update translations for gettor
commit 510c0331425839d5a1b8f36279e3682733840187 Author: Translation commit bot Date: Thu Jun 25 12:45:05 2015 + Update translations for gettor --- id/gettor.po |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/id/gettor.po b/id/gettor.po index 9830bd7..a3f8c21 100644 --- a/id/gettor.po +++ b/id/gettor.po @@ -14,7 +14,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-01-19 13:40+0100\n" -"PO-Revision-Date: 2015-06-22 15:34+\n" +"PO-Revision-Date: 2015-06-25 12:41+\n" "Last-Translator: Zamani Karmana \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/torproject/language/id/)\n" "MIME-Version: 1.0\n" @@ -156,13 +156,13 @@ msgstr "Cukup sertakan kata kunci 'split' pada baris terpisah (bagian ini\npenti msgid "" "Sending this text in an email to GetTor will cause it to send you \n" "the Tor Browser Bundle in a number of 1,4MB attachments." -msgstr "Dengan mengirimkan email berisi teks ini ke GetTor\nAnda akan menerima bundel 'Tor Browser' dengan file pelengkap berukuran 1,4MB." +msgstr "Dengan mengirimkan teks ini melalui surel ke GetTor akan membuat GetTor\nmengirimkan Tor Browser Bundle dalam lampiran sebesar 1,4MB." #: lib/gettor/i18n.py:110 msgid "" "After having received all parts, you need to re-assemble them to \n" "one package again. This is done as follows:" -msgstr "Setelah menerima seluruh isi paket, Anda perlu menyusunnya kembali\nmenjadi satu paket. Caranya adalah sebagai berikut:" +msgstr "Setelah menerima semua bagian paket, Anda perlu menyusunnya kembali\nmenjadi satu paket. Caranya adalah sebagai berikut:" #: lib/gettor/i18n.py:113 msgid "1.) Save all received attachments into one folder on your disk." ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/liveusb-creator] Update translations for liveusb-creator
commit a79e2196dfc5e6e00dc61e820c427e4447552a56 Author: Translation commit bot Date: Thu Jun 25 12:45:32 2015 + Update translations for liveusb-creator --- id/id.po |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/id/id.po b/id/id.po index 8741286..b9dbbda 100644 --- a/id/id.po +++ b/id/id.po @@ -14,7 +14,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-05-02 21:10+0200\n" -"PO-Revision-Date: 2015-06-22 15:35+\n" +"PO-Revision-Date: 2015-06-25 12:38+\n" "Last-Translator: Zamani Karmana \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/torproject/language/id/)\n" "MIME-Version: 1.0\n" @@ -136,7 +136,7 @@ msgstr "Membuat %sMB penyimpanan persisten" #: ../liveusb/gui.py:553 msgid "" "Device is not yet mounted, so we cannot determine the amount of free space." -msgstr "Device belum dipasang, jadi kita tidak bisa menentukan jumlah space yang kosong/tersedia" +msgstr "Perangkat belum terkait, sehingga kami tidak bisa memperkirakan sisa ruang kosong yang ada." #: ../liveusb/dialog.py:157 #, python-format ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/https_everywhere_completed] Update translations for https_everywhere_completed
commit aeb368c3aae3c2c8cbb3d8220eee20e02cda87ed Author: Translation commit bot Date: Thu Jun 25 12:45:28 2015 + Update translations for https_everywhere_completed --- id/https-everywhere.dtd |2 +- id/ssl-observatory.dtd |8 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/id/https-everywhere.dtd b/id/https-everywhere.dtd index 25969c6..52aa6e7 100644 --- a/id/https-everywhere.dtd +++ b/id/https-everywhere.dtd @@ -19,7 +19,7 @@ - + diff --git a/id/ssl-observatory.dtd b/id/ssl-observatory.dtd index e695864..fc811d8 100644 --- a/id/ssl-observatory.dtd +++ b/id/ssl-observatory.dtd @@ -65,10 +65,10 @@ Mouseover the options for further details:">--> https://www.something.com, sertifikat -diterima oleh observatory akan menunjukkan bahwa seseorang telah mengunjungi -www.something.com, tetapi tidak mengetahui siapa yg telah mengunjungi atau apa halaman spesifik mereka -terlihat pada mousover the options untuk detail lebih lanjut"> +"Sebagai contoh, ketika Anda mengunjungi https://www.something.com, sertifikat +diterima oleh Observatory akan mengindikasikan bahwa seseorang mengunjungi +www.something.com, tetapi bukan siapa yang mengunjungi situs tersebut, atau +halaman yang mereka lihat. Gerakkan tetikus ke atas opsi untuk perincian lebih lanjut:"> ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/gettor_completed] Update translations for gettor_completed
commit 568722e15c20b15f59dbd213e6dd656a170929fd Author: Translation commit bot Date: Thu Jun 25 12:45:10 2015 + Update translations for gettor_completed --- id/gettor.po |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/id/gettor.po b/id/gettor.po index 9830bd7..a3f8c21 100644 --- a/id/gettor.po +++ b/id/gettor.po @@ -14,7 +14,7 @@ msgstr "" "Project-Id-Version: The Tor Project\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-01-19 13:40+0100\n" -"PO-Revision-Date: 2015-06-22 15:34+\n" +"PO-Revision-Date: 2015-06-25 12:41+\n" "Last-Translator: Zamani Karmana \n" "Language-Team: Indonesian (http://www.transifex.com/projects/p/torproject/language/id/)\n" "MIME-Version: 1.0\n" @@ -156,13 +156,13 @@ msgstr "Cukup sertakan kata kunci 'split' pada baris terpisah (bagian ini\npenti msgid "" "Sending this text in an email to GetTor will cause it to send you \n" "the Tor Browser Bundle in a number of 1,4MB attachments." -msgstr "Dengan mengirimkan email berisi teks ini ke GetTor\nAnda akan menerima bundel 'Tor Browser' dengan file pelengkap berukuran 1,4MB." +msgstr "Dengan mengirimkan teks ini melalui surel ke GetTor akan membuat GetTor\nmengirimkan Tor Browser Bundle dalam lampiran sebesar 1,4MB." #: lib/gettor/i18n.py:110 msgid "" "After having received all parts, you need to re-assemble them to \n" "one package again. This is done as follows:" -msgstr "Setelah menerima seluruh isi paket, Anda perlu menyusunnya kembali\nmenjadi satu paket. Caranya adalah sebagai berikut:" +msgstr "Setelah menerima semua bagian paket, Anda perlu menyusunnya kembali\nmenjadi satu paket. Caranya adalah sebagai berikut:" #: lib/gettor/i18n.py:113 msgid "1.) Save all received attachments into one folder on your disk." ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [tor-browser-bundle/maint-4.5] Preparations for 4.5.3
commit 208ed4d69784fe319231b403b63ce503b849b708 Author: Georg Koppen Date: Thu Jun 25 12:26:35 2015 + Preparations for 4.5.3 --- Bundle-Data/Docs/ChangeLog.txt| 11 +++ gitian/versions | 12 ++-- tools/update-responses/config.yml | 10 +- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/Bundle-Data/Docs/ChangeLog.txt b/Bundle-Data/Docs/ChangeLog.txt index e986e5c..c25ab38 100644 --- a/Bundle-Data/Docs/ChangeLog.txt +++ b/Bundle-Data/Docs/ChangeLog.txt @@ -1,3 +1,14 @@ +Tor Browser 4.5.3 -- June 30 2015 + * All Platforms + * Update Firefox to 31.8.0esr + * Update OpenSSL to 1.0.1o + * Update NoScript to 2.6.9.27 + * Update Torbutton to 1.9.2.8 + * Bug 14429: Make sure the automatic resizing is disabled + * Translation updates + * Bug 16397: Fix crash related to disabling SVG + * Bug 16403: Set search parameters for Disconnect + Tor Browser 5.0a2 -- June 15 2015 * All Platforms * Update Tor to 0.2.7.1-alpha diff --git a/gitian/versions b/gitian/versions index a073427..940c8b4 100755 --- a/gitian/versions +++ b/gitian/versions @@ -4,14 +4,14 @@ BUILD_PT_BUNDLES=1 VERIFY_TAGS=1 -FIREFOX_VERSION=31.7.0esr +FIREFOX_VERSION=31.8.0esr TORBROWSER_UPDATE_CHANNEL=release -TORBROWSER_TAG=tor-browser-${FIREFOX_VERSION}-4.5-2-build1 +TORBROWSER_TAG=tor-browser-${FIREFOX_VERSION}-4.5-1-build1 TOR_TAG=tor-0.2.6.9 TORLAUNCHER_TAG=0.2.7.5 -TORBUTTON_TAG=1.9.2.6 +TORBUTTON_TAG=1.9.2.8 HTTPSE_TAG=5.0.5 NSIS_TAG=v0.3 ZLIB_TAG=v1.2.8 @@ -38,7 +38,7 @@ GITIAN_TAG=tor-browser-builder-3.x-8 OPENSSL_VER=1.0.1o GMP_VER=5.1.3 FIREFOX_LANG_VER=$FIREFOX_VERSION -FIREFOX_LANG_BUILD=build2 +FIREFOX_LANG_BUILD=build1 BINUTILS_VER=2.24 GCC_VER=4.9.1 PYTHON_VER=2.7.5 @@ -57,7 +57,7 @@ GO_VER=1.4.2 ## File names for the source packages OPENSSL_PACKAGE=openssl-${OPENSSL_VER}.tar.gz GMP_PACKAGE=gmp-${GMP_VER}.tar.bz2 -NOSCRIPT_PACKAGE=noscript_security_suite-2.6.9.26-sm+fn+fx.xpi +NOSCRIPT_PACKAGE=noscript_security_suite-2.6.9.27-sm+fn+fx.xpi TOOLCHAIN4_PACKAGE=x86_64-apple-darwin10.tar.xz TOOLCHAIN4_OLD_PACKAGE=multiarch-darwin11-cctools127.2-gcc42-5666.3-llvmgcc42-2336.1-Linux-120724.tar.xz OSXSDK_PACKAGE=apple-uni-sdk-10.6_20110407-0.flosoft1_i386.deb @@ -84,7 +84,7 @@ GMP_HASH=752079520b4690531171d0f4532e40f08600215feefede70b24fabdc6f1ab160 OSXSDK_HASH=6602d8d5ddb371fbc02e2a5967d9bd0cd7358d46f9417753c8234b923f2ea6fc TOOLCHAIN4_HASH=7b71bfe02820409b994c5c33a7eab81a81c72550f5da85ff7af70da3da244645 TOOLCHAIN4_OLD_HASH=65c1b2d302358a6b95a26c6828a66908a199276193bb0b268f2dcc1a997731e9 -NOSCRIPT_HASH=06d9fa6093378682a7fabfc0b2d156dfafcfda749ddd802970ce14d1860e6a3e +NOSCRIPT_HASH=a59a2150a4fa03091afd670d86333b60b6516ccd104bcef918afe99460fb436a MSVCR100_HASH=1221a09484964a6f38af5e34ee292b9afefccb3dc6e55435fd3aaf7c235d9067 PYCRYPTO_HASH=f2ce1e989b272cfcb677616763e0a2e7ec659effa67a88aa92b3a65528f60a3c ARGPARSE_HASH=ddaf4b0a618335a32b6664d4ae038a1de8fbada3b25033f9021510ed2b3941a4 diff --git a/tools/update-responses/config.yml b/tools/update-responses/config.yml index fd9bd23..06d07dd 100644 --- a/tools/update-responses/config.yml +++ b/tools/update-responses/config.yml @@ -10,14 +10,14 @@ build_targets: osx64: Darwin_x86_64-gcc3 channels: alpha: 5.0a2 -release: 4.5.2 +release: 4.5.3 versions: -4.5.2: -platformVersion: 31.7.0 +4.5.3: +platformVersion: 31.8.0 detailsURL: https://www.torproject.org/projects/torbrowser.html.en -download_url: https://www.torproject.org/dist/torbrowser/4.5.2 +download_url: https://www.torproject.org/dist/torbrowser/4.5.3 incremental_from: - - 4.5.1 + - 4.5.2 migrate_archs: osx32: osx64 osx32: ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [onionoo/master] Avoid error because of non-existant descriptor type
commit c04a33a074a9815b0c146192b3b14225da15f7de Author: Karsten Loesing Date: Thu Jun 25 14:15:26 2015 +0200 Avoid error because of non-existant descriptor type When splitting up the hourly updater into three phases, we lost the ability to skip downloading descriptors we're not going to process later. Hence, we'll get an error because CollecTor doesn't serve bridge-pool assignments anymore. But we don't parse them anyway, so we can as well remove them from our list of descriptors we might care about. That avoids this specific error. --- .../org/torproject/onionoo/updater/DescriptorDownloader.java|3 --- .../java/org/torproject/onionoo/updater/DescriptorHistory.java |1 - .../java/org/torproject/onionoo/updater/DescriptorQueue.java|6 -- .../java/org/torproject/onionoo/updater/DescriptorSource.java |7 --- .../java/org/torproject/onionoo/updater/DescriptorType.java |1 - .../org/torproject/onionoo/updater/DummyDescriptorSource.java |1 - 6 files changed, 19 deletions(-) diff --git a/src/main/java/org/torproject/onionoo/updater/DescriptorDownloader.java b/src/main/java/org/torproject/onionoo/updater/DescriptorDownloader.java index 9e2f80d..d5b6c49 100644 --- a/src/main/java/org/torproject/onionoo/updater/DescriptorDownloader.java +++ b/src/main/java/org/torproject/onionoo/updater/DescriptorDownloader.java @@ -52,9 +52,6 @@ class DescriptorDownloader { case BRIDGE_EXTRA_INFOS: this.directory = "bridge-descriptors/extra-infos/"; break; -case BRIDGE_POOL_ASSIGNMENTS: - this.directory = "bridge-pool-assignments/"; - break; default: log.error("Unknown descriptor type."); return; diff --git a/src/main/java/org/torproject/onionoo/updater/DescriptorHistory.java b/src/main/java/org/torproject/onionoo/updater/DescriptorHistory.java index 0f6f578..e6d911e 100644 --- a/src/main/java/org/torproject/onionoo/updater/DescriptorHistory.java +++ b/src/main/java/org/torproject/onionoo/updater/DescriptorHistory.java @@ -8,5 +8,4 @@ enum DescriptorHistory { BRIDGE_STATUS_HISTORY, BRIDGE_SERVER_HISTORY, BRIDGE_EXTRAINFO_HISTORY, - BRIDGE_POOLASSIGN_HISTORY, } \ No newline at end of file diff --git a/src/main/java/org/torproject/onionoo/updater/DescriptorQueue.java b/src/main/java/org/torproject/onionoo/updater/DescriptorQueue.java index b86d585..6740ca9 100644 --- a/src/main/java/org/torproject/onionoo/updater/DescriptorQueue.java +++ b/src/main/java/org/torproject/onionoo/updater/DescriptorQueue.java @@ -89,9 +89,6 @@ class DescriptorQueue { case BRIDGE_EXTRA_INFOS: directoryName = "bridge-descriptors/extra-infos"; break; -case BRIDGE_POOL_ASSIGNMENTS: - directoryName = "bridge-pool-assignments"; - break; case EXIT_LISTS: directoryName = "exit-lists"; break; @@ -133,9 +130,6 @@ class DescriptorQueue { case EXIT_LIST_HISTORY: historyFileName = "exit-list-history"; break; -case BRIDGE_POOLASSIGN_HISTORY: - historyFileName = "bridge-poolassign-history"; - break; case RELAY_CONSENSUS_HISTORY: historyFileName = "relay-consensus-history"; break; diff --git a/src/main/java/org/torproject/onionoo/updater/DescriptorSource.java b/src/main/java/org/torproject/onionoo/updater/DescriptorSource.java index b26a692..a1e489e 100644 --- a/src/main/java/org/torproject/onionoo/updater/DescriptorSource.java +++ b/src/main/java/org/torproject/onionoo/updater/DescriptorSource.java @@ -101,10 +101,6 @@ public class DescriptorSource { log.debug("Reading recent " + DescriptorType.BRIDGE_EXTRA_INFOS + " ..."); this.readDescriptors(DescriptorType.BRIDGE_EXTRA_INFOS, DescriptorHistory.BRIDGE_EXTRAINFO_HISTORY, false); -log.debug("Reading recent " + DescriptorType.BRIDGE_POOL_ASSIGNMENTS -+ " ..."); -this.readDescriptors(DescriptorType.BRIDGE_POOL_ASSIGNMENTS, -DescriptorHistory.BRIDGE_POOLASSIGN_HISTORY, false); log.debug("Reading recent " + DescriptorType.BRIDGE_STATUSES + " ..."); this.readDescriptors(DescriptorType.BRIDGE_STATUSES, DescriptorHistory.BRIDGE_STATUS_HISTORY, false); @@ -147,9 +143,6 @@ public class DescriptorSource { case BRIDGE_EXTRA_INFOS: log.info("Read recent bridge extra-info descriptors"); break; -case BRIDGE_POOL_ASSIGNMENTS: - log.info("Read recent bridge-pool assignments"); - break; } } diff --git a/src/main/java/org/torproject/onionoo/updater/DescriptorType.java b/src/main/java/org/torproject/onionoo/updater/DescriptorType.java index 41956da..60d2759 100644 --- a/src/main/java/org/torproject/onionoo/updater/DescriptorType.java +++ b/src/main/java/org/torproject/onionoo/updater/DescriptorType.java @@ -10,6 +10,5 @@ public enum DescriptorType { BRIDGE_STATUSES, BRIDGE_SERVER_DESCRIPTORS, BRIDGE_EXTRA_INFOS, - BRIDGE_POOL_ASSIGNMENTS, } diff --git a/src/tes
[tor-commits] [user-manual/master] Add section on downloading, and TODO file
commit e13ef5f34bc189ecd2d5c96afe3267d544225cee Author: Harmony Date: Thu Jun 25 11:29:51 2015 + Add section on downloading, and TODO file --- C/downloading.page | 131 TODO | 55 ++ 2 files changed, 186 insertions(+) diff --git a/C/downloading.page b/C/downloading.page new file mode 100644 index 000..31b5b7f --- /dev/null +++ b/C/downloading.page @@ -0,0 +1,131 @@ +http://projectmallard.org/1.0/"; + type="topic" + id="downloading"> + + + How to download Tor Browser + + + +Downloading + + +The safest and simplest way to download Tor Browser is from the official +Tor Project website at https://www.torproject.org. Your connection to +the site will be secured using +HTTPS, so you can be sure that no +one is tampering with your copy of the software while you download it. + + + +However, there may be times when you cannot access the Tor Project +website: for example, it could be blocked on your network. If this +happens, you can use one of the alternative download methods listed +below. + + + +Satori + + Satori is an add-on for the Chrome or Chromium browsers that allows you + to download several security and privacy programs from different + sources. + + + To download Tor Browser using Satori: + + + + + Install Satori from the Chrome App Store. + + + + + Select Satori from your browserâs Apps menu. + + + + + When Satori opens, click on your preferred language. A menu will open + listing the available downloads for that language. Find the entry for + Tor Browser under the name of your operating system. Select + either âAâ or âBâ after the name of the program â each one represents + a different source from which to get the software. Your download will + then begin. + + + + + Wait for your download to finish, then find the âGenerate Hashâ + section in Satoriâs menu and click âSelect Filesâ. + + + + + Select the downloaded Tor Browser file. Satori will display the + checksum of the file, which you should compare with the softwareâs + original checksum: you can find this by clicking the word âchecksumâ + after the link you clicked on to start the download. If the checksums + match, your download was successful, and you can + begin using Tor Browser. If they do not + match, you may need to try downloading again, or from a different + source. + + + + + + +GetTor + + GetTor is an email-based service that automatically responds to + messages with links to the latest version of Tor Browser, hosted at a + variety of locations, such as Dropbox. + + + + To use GetTor: + + + + + Send an email to get...@torproject.org, and in the body + of the message simply write âwindowsâ, âosxâ, or âlinuxâ, (without + quotation marks) depending on your operating system. + + + + + GetTor will respond with an email containing links from which you can + download the Tor Browser package, the cryptographic signature (needed + for verifying the download), the fingerprint of the key used to make + the signature, and the packageâs checksum. You may be offered a choice + of â32-bitâ or â64-bitâ software: this depends on the model of the + computer you are using. + + + + + + +Tor website mirrors + + A number of volunteers around the world host âmirrorsâ of the Tor + Project website. These are identical copies of all the content and + software on the main website, hosted at different IP addresses and + URLs. The Tor Project periodically checks mirrored versions of the + software to make sure they are the same as the originals. + + + + If the main Tor website is blocked for you, and the automated + distribution methods above do not work, send an email to + h...@rt.torproject.org asking for some website mirror addresses. You + should then be able to download Tor Browser as normal from these sites. + Please note that you should take extra care to verify the software you + download from a mirror, to ensure that it has not been tampered with. + + + + diff --git a/TODO b/TODO new file mode 100644 index 000..7b45e95 --- /dev/null +++ b/TODO @@ -0,0 +1,55 @@ +== +SHORT TERM +== + +ADDITIONAL SCREENSHOTS + +Produce screenshots illustrating the download methods in the âHow to +downloadâ section (Satori, GetTor, mirrors). + +SECTIONS TO ADD/EXPAND/MODIFY + +Add a section that explains how to verify the Tor Browser download in +clear and simple steps. + +Expand âUsing for the first timeâ section with guidance on +extracting/âinstallingâ Tor Browser, and locating it in the filesystem +on each OS. Cover the need to move TB to OSX Applications folder (and +not run from disk image). Take into account the change in Mac OSX +installation once a developer cert is available (ETA: August 2015) + +Modify âBridgesâ page if/when we have a domain-fronted API to +autodiscove
[tor-commits] [translation/abouttor-homepage_completed] Update translations for abouttor-homepage_completed
commit 86fa71259fe3a1955f7c00171355ee499be4ab8a Author: Translation commit bot Date: Thu Jun 25 10:15:52 2015 + Update translations for abouttor-homepage_completed --- nl/aboutTor.dtd |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nl/aboutTor.dtd b/nl/aboutTor.dtd index 6e92558..4abee58 100644 --- a/nl/aboutTor.dtd +++ b/nl/aboutTor.dtd @@ -25,7 +25,7 @@ https://startpage.com/rth/search";> https://duckduckgo.com/html/";> -https://search.disconnect.me/searchTerms/search?ses=Google&location_option=NL";> +https://search.disconnect.me/searchTerms/search?ses=Google&location_option=US&source=tor";> ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/abouttor-homepage_completed] Update translations for abouttor-homepage_completed
commit a647b0d95577c3afdd992807a85c041cb302e366 Author: Translation commit bot Date: Thu Jun 25 08:45:46 2015 + Update translations for abouttor-homepage_completed --- zh_CN/aboutTor.dtd |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zh_CN/aboutTor.dtd b/zh_CN/aboutTor.dtd index dca1bba..cbb7ea7 100644 --- a/zh_CN/aboutTor.dtd +++ b/zh_CN/aboutTor.dtd @@ -25,7 +25,7 @@ https://startpage.com/rth/search";> https://duckduckgo.com/html/";> -https://search.disconnect.me/searchTerms/search?ses=Google&location_option=CN";> +https://search.disconnect.me/searchTerms/search?ses=Google&location_option=US&source=tor";> ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [translation/abouttor-homepage] Update translations for abouttor-homepage
commit a6fa031e13660c715c2dfcdca2042c31444c9f9a Author: Translation commit bot Date: Thu Jun 25 08:17:08 2015 + Update translations for abouttor-homepage --- ach/aboutTor.dtd |2 +- ady/aboutTor.dtd |2 +- af/aboutTor.dtd |2 +- ak/aboutTor.dtd |2 +- am/aboutTor.dtd |2 +- ar/aboutTor.dtd |2 +- arn/aboutTor.dtd |2 +- ast/aboutTor.dtd |2 +- az/aboutTor.dtd |2 +- ba/aboutTor.dtd |2 +- be/aboutTor.dtd |2 +- bg/aboutTor.dtd |2 +- bn/aboutTor.dtd |2 +- bn_IN/aboutTor.dtd |2 +- bo/aboutTor.dtd |2 +- br/aboutTor.dtd |2 +- bs/aboutTor.dtd |2 +- ca/aboutTor.dtd |2 +- cs/aboutTor.dtd |2 +- csb/aboutTor.dtd |2 +- cv/aboutTor.dtd |2 +- cy/aboutTor.dtd |2 +- cy_GB/aboutTor.dtd |2 +- da/aboutTor.dtd |2 +- de/aboutTor.dtd |2 +- dz/aboutTor.dtd |2 +- el/aboutTor.dtd |2 +- en/aboutTor.dtd |2 +- en_GB/aboutTor.dtd |2 +- eo/aboutTor.dtd |2 +- es/aboutTor.dtd |2 +- es_AR/aboutTor.dtd |2 +- es_CL/aboutTor.dtd |2 +- es_CO/aboutTor.dtd |2 +- es_MX/aboutTor.dtd |2 +- et/aboutTor.dtd |2 +- eu/aboutTor.dtd |2 +- fa/aboutTor.dtd |2 +- fi/aboutTor.dtd |2 +- fil/aboutTor.dtd |2 +- fo/aboutTor.dtd |2 +- fr/aboutTor.dtd |2 +- fr_CA/aboutTor.dtd |2 +- fur/aboutTor.dtd |2 +- fy/aboutTor.dtd |2 +- ga/aboutTor.dtd |2 +- gd/aboutTor.dtd |2 +- gl/aboutTor.dtd |2 +- gu/aboutTor.dtd |2 +- gu_IN/aboutTor.dtd |2 +- gun/aboutTor.dtd |2 +- ha/aboutTor.dtd |2 +- he/aboutTor.dtd |2 +- hi/aboutTor.dtd |2 +- hr/aboutTor.dtd |2 +- hr_HR/aboutTor.dtd |2 +- ht/aboutTor.dtd |2 +- hu/aboutTor.dtd |2 +- hy/aboutTor.dtd |2 +- hy_AM/aboutTor.dtd |2 +- ia/aboutTor.dtd |2 +- id/aboutTor.dtd |2 +- is/aboutTor.dtd |2 +- it/aboutTor.dtd |2 +- ja/aboutTor.dtd |2 +- jbo/aboutTor.dtd |2 +- jv/aboutTor.dtd |2 +- ka/aboutTor.dtd |2 +- kk/aboutTor.dtd |2 +- km/aboutTor.dtd |2 +- kn/aboutTor.dtd |2 +- ko/aboutTor.dtd |2 +- ko_KR/aboutTor.dtd |2 +- ku/aboutTor.dtd |2 +- ku_IQ/aboutTor.dtd |2 +- kw/aboutTor.dtd |2 +- ky/aboutTor.dtd |2 +- la/aboutTor.dtd |2 +- lb/aboutTor.dtd |2 +- lg/aboutTor.dtd |2 +- ln/aboutTor.dtd |2 +- lo/aboutTor.dtd |2 +- lt/aboutTor.dtd |2 +- lv/aboutTor.dtd |2 +- mg/aboutTor.dtd |2 +- mi/aboutTor.dtd |2 +- mk/aboutTor.dtd |2 +- ml/aboutTor.dtd |2 +- mn/aboutTor.dtd |2 +- mr/aboutTor.dtd |2 +- ms_MY/aboutTor.dtd |2 +- mt/aboutTor.dtd |2 +- my/aboutTor.dtd |2 +- nah/aboutTor.dtd |2 +- nap/aboutTor.dtd |2 +- nb/aboutTor.dtd |2 +- nds/aboutTor.dtd |2 +- ne/aboutTor.dtd |2 +- nl/aboutTor.dtd |2 +- nl_BE/aboutTor.dtd |2 +- nn/aboutTor.dtd |2 +- nso/aboutTor.dtd |2 +- oc/aboutTor.dtd |2 +- or/aboutTor.dtd |2 +- pa/aboutTor.dtd |2 +- pap/aboutTor.dtd |2 +- pl/aboutTor.dtd |2 +- pms/aboutTor.dtd |2 +- ps/aboutTor.dtd |2 +- pt/aboutTor.dtd |2 +- pt_BR/aboutTor.dtd |2 +- ro/aboutTor.dtd |2 +- ru/aboutTor.dtd |2 +- ru@petr1708/aboutTor.dtd |2 +- sa/aboutTor.dtd |2 +- scn/aboutTor.dtd |2 +- sco/aboutTor.dtd |2 +- si/aboutTor.dtd |2 +- si_LK/aboutTor.dtd |2 +- sk/aboutTor.dtd |2 +- sk_SK/aboutTor.dtd |2 +- sl/aboutTor.dtd |2 +- sl_SI/aboutTor.dtd |2 +- sn/aboutTor.dtd |2 +- so/aboutTor.dtd |2 +- son/aboutTor.dtd |2 +- sq/aboutTor.dtd |2 +- sr/aboutTor.dtd |2 +- sr@latin/aboutTor.dtd|2 +- st/aboutTor.dtd |2 +- su/aboutTor.dtd |2 +- sv/aboutTor.dtd |2 +- sw/aboutTor.dtd |2 +- szl/aboutTor.dtd |2 +- ta/a
[tor-commits] [translation/abouttor-homepage_completed] Update translations for abouttor-homepage_completed
commit 8417e76c7b78e53622fbd51cd75420ddbec372c7 Author: Translation commit bot Date: Thu Jun 25 08:17:14 2015 + Update translations for abouttor-homepage_completed --- en/aboutTor.dtd |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/en/aboutTor.dtd b/en/aboutTor.dtd index 771f8ae..b923233 100644 --- a/en/aboutTor.dtd +++ b/en/aboutTor.dtd @@ -25,7 +25,7 @@ https://startpage.com/rth/search";> https://duckduckgo.com/html/";> -https://search.disconnect.me/searchTerms/search?ses=Google&location_option=US";> +https://search.disconnect.me/searchTerms/search?ses=Google&location_option=US&source=tor";> ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Merge branch 'fix/12506-separate-dist-dirs' into develop
commit 5019761881c7807ab0f09f0728f337b5ce857ca5 Merge: dfbc8e0 a51f553 Author: Isis Lovecruft Date: Thu Jun 25 03:17:58 2015 + Merge branch 'fix/12506-separate-dist-dirs' into develop doc/sphinx/source/bridgedb.HTTPServer.rst |8 - doc/sphinx/source/bridgedb.https.rst | 11 + doc/sphinx/source/bridgedb.rst |2 +- doc/sphinx/source/conf.py |4 +- lib/bridgedb/Bridges.py| 51 +- lib/bridgedb/Dist.py | 664 ++-- lib/bridgedb/Filters.py| 41 +- lib/bridgedb/HTTPServer.py | 935 - lib/bridgedb/Main.py | 116 +-- lib/bridgedb/bridgerequest.py | 23 +- lib/bridgedb/bridges.py| 123 ++- lib/bridgedb/email/autoresponder.py| 16 +- lib/bridgedb/email/request.py | 15 - lib/bridgedb/email/templates.py| 14 +- lib/bridgedb/https/__init__.py |1 + lib/bridgedb/https/request.py | 143 +++ lib/bridgedb/https/server.py | 909 + .../https/templates/assets/css/bootstrap.min.css |7 + lib/bridgedb/https/templates/assets/css/custom.css | 158 +++ .../templates/assets/css/font-awesome-ie7.min.css | 384 +++ .../templates/assets/css/font-awesome.min.css | 403 lib/bridgedb/https/templates/assets/css/main.css | 24 + .../templates/assets/font/fontawesome-webfont.eot | Bin 0 -> 37405 bytes .../templates/assets/font/fontawesome-webfont.svg | 399 .../templates/assets/font/fontawesome-webfont.ttf | Bin 0 -> 79076 bytes .../templates/assets/font/fontawesome-webfont.woff | Bin 0 -> 43572 bytes .../https/templates/assets/font/lato-bold.woff | Bin 0 -> 46160 bytes .../https/templates/assets/font/lato-italic.woff | Bin 0 -> 47168 bytes .../https/templates/assets/font/lato-regular.woff | Bin 0 -> 46108 bytes .../https/templates/assets/tor-roots-blue.svg | 95 ++ lib/bridgedb/https/templates/assets/tor.svg|6 + lib/bridgedb/https/templates/base.html | 108 ++ lib/bridgedb/https/templates/bridges.html | 203 lib/bridgedb/https/templates/captcha.html | 63 ++ lib/bridgedb/https/templates/howto.html| 39 + lib/bridgedb/https/templates/index.html| 43 + lib/bridgedb/https/templates/options.html | 164 +++ lib/bridgedb/https/templates/robots.txt| 1079 lib/bridgedb/strings.py| 270 - lib/bridgedb/templates/assets/bridgedb.png | Bin 2946 -> 0 bytes .../templates/assets/css/bootstrap.min.css |7 - lib/bridgedb/templates/assets/css/custom.css | 158 --- .../templates/assets/css/font-awesome-ie7.min.css | 384 --- .../templates/assets/css/font-awesome.min.css | 403 lib/bridgedb/templates/assets/css/main.css | 24 - .../templates/assets/font/fontawesome-webfont.eot | Bin 37405 -> 0 bytes .../templates/assets/font/fontawesome-webfont.svg | 399 .../templates/assets/font/fontawesome-webfont.ttf | Bin 79076 -> 0 bytes .../templates/assets/font/fontawesome-webfont.woff | Bin 43572 -> 0 bytes lib/bridgedb/templates/assets/font/lato-bold.woff | Bin 46160 -> 0 bytes .../templates/assets/font/lato-italic.woff | Bin 47168 -> 0 bytes .../templates/assets/font/lato-regular.woff| Bin 46108 -> 0 bytes lib/bridgedb/templates/assets/tor-roots-blue.svg | 95 -- lib/bridgedb/templates/assets/tor.svg |6 - lib/bridgedb/templates/base.html | 108 -- lib/bridgedb/templates/bridgedb.asc| 252 - lib/bridgedb/templates/bridges.html| 203 lib/bridgedb/templates/captcha.html| 63 -- lib/bridgedb/templates/howto.html | 39 - lib/bridgedb/templates/index.html | 43 - lib/bridgedb/templates/options.html| 164 --- lib/bridgedb/templates/robots.txt | 1079 lib/bridgedb/test/email_helpers.py | 36 +- lib/bridgedb/test/https_helpers.py | 130 +++ lib/bridgedb/test/legacy_Tests.py | 69 +- lib/bridgedb/test/test_Dist.py | 239 + lib/bridgedb/test/test_HTTPServer.py | 804 --- lib/bridgedb/test/test_Main.py | 101 +- lib/bridgedb/test/test_bridgerequest.py| 20 +- lib/bridgedb/test/test_bridges.py | 83 +- lib/bridgedb/test/test_email_server.py |5 +- lib/bridgedb/test/test_https_request.py| 91 ++ lib/bridgedb/test/test_htt
[tor-commits] [bridgedb/develop] Merge branch 'fix/12029-distribute-module' into develop
commit 4ebb7842a53b513996604b3a8442fc0c5fc0e3fd Merge: 5019761 8d4bb32 Author: Isis Lovecruft Date: Thu Jun 25 03:24:18 2015 + Merge branch 'fix/12029-distribute-module' into develop doc/sphinx/source/bridgedb.Dist.rst |8 - doc/sphinx/source/bridgedb.Filters.rst|8 - doc/sphinx/source/bridgedb.email.rst |1 + doc/sphinx/source/bridgedb.filters.rst|8 + doc/sphinx/source/bridgedb.https.rst |1 + doc/sphinx/source/bridgedb.rst|3 +- doc/sphinx/source/conf.py |5 +- lib/bridgedb/Bridges.py | 101 +++-- lib/bridgedb/Dist.py | 559 - lib/bridgedb/Filters.py | 116 - lib/bridgedb/Main.py | 36 +- lib/bridgedb/bridgerequest.py | 77 ++-- lib/bridgedb/bridges.py | 115 +++-- lib/bridgedb/distribute.py| 275 lib/bridgedb/email/autoresponder.py | 13 +- lib/bridgedb/email/distributor.py | 219 ++ lib/bridgedb/email/request.py |6 +- lib/bridgedb/email/server.py |4 +- lib/bridgedb/email/templates.py |2 +- lib/bridgedb/filters.py | 238 +++ lib/bridgedb/https/distributor.py | 328 +++ lib/bridgedb/https/request.py |2 +- lib/bridgedb/https/server.py |6 +- lib/bridgedb/interfaces.py| 56 ++- lib/bridgedb/parse/addr.py| 13 +- lib/bridgedb/persistent.py| 16 +- lib/bridgedb/test/email_helpers.py| 24 +- lib/bridgedb/test/https_helpers.py|6 +- lib/bridgedb/test/legacy_Tests.py | 301 + lib/bridgedb/test/test_Dist.py| 239 --- lib/bridgedb/test/test_Main.py|6 +- lib/bridgedb/test/test_bridges.py | 10 +- lib/bridgedb/test/test_distribute.py | 44 ++ lib/bridgedb/test/test_email_autoresponder.py |2 +- lib/bridgedb/test/test_email_distributor.py | 258 lib/bridgedb/test/test_email_request.py | 16 +- lib/bridgedb/test/test_email_server.py|6 +- lib/bridgedb/test/test_filters.py | 333 +++ lib/bridgedb/test/test_https_distributor.py | 405 ++ lib/bridgedb/test/test_https_server.py|2 +- lib/bridgedb/test/test_interfaces.py | 55 +++ lib/bridgedb/test/util.py | 48 ++- lib/bridgedb/util.py | 16 + 43 files changed, 2561 insertions(+), 1426 deletions(-) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Merge branch 'hotfix/0.3.2-pep440' into develop
commit 300bc1110c686285080d4e5e162d7fdcc9dc6480 Merge: 8bf4f5f 6fb22aa Author: Isis Lovecruft Date: Thu Jun 25 06:43:43 2015 + Merge branch 'hotfix/0.3.2-pep440' into develop MANIFEST.in |2 + bridgedb/_version.py | 551 ++ setup.cfg| 21 + setup.py | 18 - versioneer.py| 2045 +- 5 files changed, 1974 insertions(+), 663 deletions(-) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Update versioneer to newest version in order to be PEP440 compliant.
commit 6fb22aaa33f271cbaad4f71a265a4298c1115223 Author: Isis Lovecruft Date: Thu Jun 25 05:04:32 2015 + Update versioneer to newest version in order to be PEP440 compliant. --- MANIFEST.in |2 + bridgedb/_version.py | 551 ++ setup.cfg| 21 + setup.py | 18 - versioneer.py| 2045 +- 5 files changed, 1974 insertions(+), 663 deletions(-) diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 000..910eb85 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,2 @@ +include versioneer.py +include bridgedb/_version.py diff --git a/bridgedb/_version.py b/bridgedb/_version.py index 8e9faf1..6890364 100644 --- a/bridgedb/_version.py +++ b/bridgedb/_version.py @@ -1,197 +1,460 @@ -IN_LONG_VERSION_PY = True # This file helps to compute a version number in source trees obtained from # git-archive tarball (such as those provided by githubs download-from-tag -# feature). Distribution tarballs (build by setup.py sdist) and build +# feature). Distribution tarballs (built by setup.py sdist) and build # directories (produced by setup.py build) will contain a much shorter file # that just contains the computed version number. # This file is released into the public domain. Generated by -# versioneer-0.7+ (https://github.com/warner/python-versioneer) - -# these strings will be replaced by git during git-archive -git_refnames = "$Format:%d$" -git_full = "$Format:%H$" - +# versioneer-0.15 (https://github.com/warner/python-versioneer) +import errno +import os +import re import subprocess import sys -def run_command(args, cwd=None, verbose=False): -try: -# remember shell=False, so use git.cmd on windows, not just git -p = subprocess.Popen(args, stdout=subprocess.PIPE, cwd=cwd) -except EnvironmentError: -e = sys.exc_info()[1] + +def get_keywords(): +# these strings will be replaced by git during git-archive. +# setup.py/versioneer.py will grep for the variable names, so they must +# each be defined on a line of their own. _version.py will just call +# get_keywords(). +git_refnames = "$Format:%d$" +git_full = "$Format:%H$" +keywords = {"refnames": git_refnames, "full": git_full} +return keywords + + +class VersioneerConfig: +pass + + +def get_config(): +# these strings are filled in when 'setup.py versioneer' creates +# _version.py +cfg = VersioneerConfig() +cfg.VCS = "git" +cfg.style = "pep440" +cfg.tag_prefix = "bridgedb-" +cfg.parentdir_prefix = "bridgedb-" +cfg.versionfile_source = "bridgedb/_version.py" +cfg.verbose = False +return cfg + + +class NotThisMethod(Exception): +pass + + +LONG_VERSION_PY = {} +HANDLERS = {} + + +def register_vcs_handler(vcs, method): # decorator +def decorate(f): +if vcs not in HANDLERS: +HANDLERS[vcs] = {} +HANDLERS[vcs][method] = f +return f +return decorate + + +def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False): +assert isinstance(commands, list) +p = None +for c in commands: +try: +dispcmd = str([c] + args) +# remember shell=False, so use git.cmd on windows, not just git +p = subprocess.Popen([c] + args, cwd=cwd, stdout=subprocess.PIPE, + stderr=(subprocess.PIPE if hide_stderr + else None)) +break +except EnvironmentError: +e = sys.exc_info()[1] +if e.errno == errno.ENOENT: +continue +if verbose: +print("unable to run %s" % dispcmd) +print(e) +return None +else: if verbose: -print("unable to run %s" % args[0]) -print(e) +print("unable to find command, tried %s" % (commands,)) return None stdout = p.communicate()[0].strip() -if sys.version >= '3': +if sys.version_info[0] >= 3: stdout = stdout.decode() if p.returncode != 0: if verbose: -print("unable to run %s (error)" % args[0]) +print("unable to run %s (error)" % dispcmd) return None return stdout -import sys -import re -import os.path +def versions_from_parentdir(parentdir_prefix, root, verbose): +# Source tarballs conventionally unpack into a directory that includes +# both the project name and a version string. +dirname = os.path.basename(root) +if not dirname.startswith(parentdir_prefix): +if verbose: +print("guessing rootdir is '%s', but '%s' doesn't start with " + "prefix '%s'" % (root, dirname, parentdir_prefix)) +raise NotThisMethod("rootdir doesn't start with parentdir_prefix") +return {"version": dirname[len(parentdir_prefix):], +"full-revisionid": None, +
[tor-commits] [bridgedb/develop] PEP8 remove extra blank line in bridgedb.bridges module.
commit 3c990f7cd86b7f2ca8799ee4b7054b5e0167620e Author: Isis Lovecruft Date: Tue May 12 07:28:26 2015 + PEP8 remove extra blank line in bridgedb.bridges module. --- lib/bridgedb/bridges.py |1 - 1 file changed, 1 deletion(-) diff --git a/lib/bridgedb/bridges.py b/lib/bridgedb/bridges.py index c98d54c..f6e1d6b 100644 --- a/lib/bridgedb/bridges.py +++ b/lib/bridgedb/bridges.py @@ -1104,7 +1104,6 @@ class Bridge(BridgeBackwardsCompatibility): ("Client requested transport %s, but bridge %s doesn't " "have any of that transport!") % (desired, self)) - unblocked = [] for pt in transports: if not sum([self.transportIsBlockedIn(cc, pt.methodname) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Define IBridge interface for sufficiently "bridge-like" things.
commit 910941c712f20816c70e06e64add5e8530218c1c Author: Isis Lovecruft Date: Tue Jun 9 00:16:37 2015 + Define IBridge interface for sufficiently "bridge-like" things. * ADD bridgedb.bridges.IBridge interface specification. * CHANGE the following classes to declare that they implement the IBridge interface: - bridgedb.bridges.BridgeAddressBase - bridgedb.bridges.PluggableTransport - bridgedb.bridges.BridgeBase - bridgedb.bridges.BridgeBackwardsCompatibility - bridgedb.bridges.Bridge Conflicts: lib/bridgedb/bridges.py --- lib/bridgedb/bridges.py | 22 ++ 1 file changed, 22 insertions(+) diff --git a/lib/bridgedb/bridges.py b/lib/bridgedb/bridges.py index 5093bef..747863a 100644 --- a/lib/bridgedb/bridges.py +++ b/lib/bridgedb/bridges.py @@ -23,6 +23,10 @@ from Crypto.Util import asn1 from Crypto.Util.number import bytes_to_long from Crypto.Util.number import long_to_bytes +from zope.interface import implementer +from zope.interface import Attribute +from zope.interface import Interface + import bridgedb.Storage from bridgedb import geo @@ -78,6 +82,18 @@ class InvalidExtraInfoSignature(MalformedBridgeInfo): """Raised if the signature on an ``@type bridge-extrainfo`` is invalid.""" +class IBridge(Interface): +"""I am a (mostly) stub interface whose primary purpose is merely to allow +other classes to signify whether or not they can be treated like a +:class:`Bridge`. +""" +fingerprint = Attribute( +("The lowercased, hexadecimal-encoded, hash digest of this Bridge's " + "public identity key.")) +address = Attribute("This Bridge's primary public IP address.") +port = Attribute("The port which this Bridge is listening on.") + + class Flags(object): """All the flags which a :class:`Bridge` may have.""" @@ -122,6 +138,7 @@ class Flags(object): self.valid = 'Valid' in flags +@implementer(IBridge) class BridgeAddressBase(object): """A base class for describing one of a :class:`Bridge`'s or a :class:`PluggableTransport`'s location, including its identity key @@ -274,6 +291,8 @@ class BridgeAddressBase(object): self._port = None + +@implementer(IBridge) class PluggableTransport(BridgeAddressBase): """A single instance of a Pluggable Transport (PT) offered by a :class:`Bridge`. @@ -589,6 +608,7 @@ class PluggableTransport(BridgeAddressBase): self._runChecks() +@implementer(IBridge) class BridgeBase(BridgeAddressBase): """The base class for all bridge implementations.""" @@ -652,6 +672,7 @@ class BridgeBase(BridgeAddressBase): del self.port +@implementer(IBridge) class BridgeBackwardsCompatibility(BridgeBase): """Backwards compatibility methods for the old Bridge class.""" @@ -841,6 +862,7 @@ class BridgeBackwardsCompatibility(BridgeBase): return db.getBridgeHistory(self.fingerprint).weightedUptime +@implementer(IBridge) class Bridge(BridgeBackwardsCompatibility): """A single bridge, and all the information we have for it. ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Refactor bridgedb.Filters and move it to bridgedb.filters.
commit 9c09ef7bdb335fd58d48d8f8ff6d79d41fbd088c Author: Isis Lovecruft Date: Tue Apr 21 05:09:32 2015 + Refactor bridgedb.Filters and move it to bridgedb.filters. --- doc/sphinx/source/bridgedb.Filters.rst |8 - doc/sphinx/source/bridgedb.filters.rst |8 + doc/sphinx/source/bridgedb.rst |2 +- doc/sphinx/source/conf.py |2 +- lib/bridgedb/Bridges.py| 12 +- lib/bridgedb/Dist.py | 25 ++- lib/bridgedb/Filters.py| 175 - lib/bridgedb/bridgerequest.py | 39 ++-- lib/bridgedb/distribute.py |2 +- lib/bridgedb/filters.py| 238 +++ lib/bridgedb/https/server.py |4 - lib/bridgedb/parse/addr.py |6 +- lib/bridgedb/persistent.py | 12 +- lib/bridgedb/test/legacy_Tests.py |5 - lib/bridgedb/test/test_Dist.py | 17 +- lib/bridgedb/test/test_filters.py | 333 16 files changed, 638 insertions(+), 250 deletions(-) diff --git a/doc/sphinx/source/bridgedb.Filters.rst b/doc/sphinx/source/bridgedb.Filters.rst deleted file mode 100644 index caf8dfc..000 --- a/doc/sphinx/source/bridgedb.Filters.rst +++ /dev/null @@ -1,8 +0,0 @@ -bridgedb.Filters - - -.. automodule:: bridgedb.Filters -:members: -:undoc-members: -:private-members: -:show-inheritance: diff --git a/doc/sphinx/source/bridgedb.filters.rst b/doc/sphinx/source/bridgedb.filters.rst new file mode 100644 index 000..9c14ce5 --- /dev/null +++ b/doc/sphinx/source/bridgedb.filters.rst @@ -0,0 +1,8 @@ +bridgedb.filters + + +.. automodule:: bridgedb.filters +:members: +:undoc-members: +:private-members: +:show-inheritance: diff --git a/doc/sphinx/source/bridgedb.rst b/doc/sphinx/source/bridgedb.rst index 31e3a90..7b1fef7 100644 --- a/doc/sphinx/source/bridgedb.rst +++ b/doc/sphinx/source/bridgedb.rst @@ -15,7 +15,7 @@ BridgeDB Package and Module Documentation bridgedb.crypto bridgedb.Dist bridgedb.email -bridgedb.Filters +bridgedb.filters bridgedb.geo bridgedb.https bridgedb.interfaces diff --git a/doc/sphinx/source/conf.py b/doc/sphinx/source/conf.py index b655c27..9b43d0f 100644 --- a/doc/sphinx/source/conf.py +++ b/doc/sphinx/source/conf.py @@ -40,7 +40,7 @@ import bridgedb.email.dkim import bridgedb.email.request import bridgedb.email.server import bridgedb.email.templates -import bridgedb.Filters +import bridgedb.filters import bridgedb.geo import bridgedb.https import bridgedb.https.request diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py index 507013d..2b56884 100644 --- a/lib/bridgedb/Bridges.py +++ b/lib/bridgedb/Bridges.py @@ -569,7 +569,7 @@ class FilteredBridgeSplitter(object): filterNames = [] for filterName in [x.func_name for x in list(ringname)]: -# Using `filterAssignBridgesToRing.func_name` gives us a messy +# Using `assignBridgesToSubring.func_name` gives us a messy # string which includes all parameters and memory addresses. Get # rid of this by partitioning at the first `(`: realFilterName = filterName.partition('(')[0] @@ -599,8 +599,8 @@ class FilteredBridgeSplitter(object): # hashring '%s'!" % (inserted, ringname))`, this log message appears: # # Jan 04 23:18:37 [INFO] Inserted 12 bridges into hashring -# frozenset([, , 4, 0) at +# frozenset([, , 4, 0) at # 0x37de578>])! # # I suppose since it contains memory addresses, it *is* technically @@ -615,10 +615,10 @@ class FilteredBridgeSplitter(object): subringName = [self.distributorName] subringNumber = None for filterName in filterNames: -if filterName.startswith('filterAssignBridgesToRing'): -subringNumber = filterName.lstrip('filterAssignBridgesToRing') +if filterName.startswith('assignBridgesToSubring'): +subringNumber = filterName.lstrip('assignBridgesToSubring') else: -subringName.append(filterName.lstrip('filterBridgesBy')) +subringName.append(filterName.lstrip('by')) if subring.name and 'Proxy' in subring.name: subringName.append('Proxy') elif subringNumber: diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index fe6b8da..9b9e35c 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -25,10 +25,10 @@ from bridgedb.Bridges import FilteredBridgeSplitter from bridgedb.crypto import getHMAC from bridgedb.crypto import getHMACFunc from bridgedb.distribute import Distributor -from bridgedb.Filters import filterAssignBridgesToRing -from bridgedb.Filters import filterBridgesByRules -from bridgedb.Filters import filterBridgesByIP4 -from bridgedb.Filters import filterBri
[tor-commits] [bridgedb/develop] Declare that b.test.util.DummyBridge and decendents implement IBridge.
commit 8d4bb32e075b806e7e99faa07e41f79701f47d93 Author: Isis Lovecruft Date: Tue Jun 9 00:19:49 2015 + Declare that b.test.util.DummyBridge and decendents implement IBridge. This allows for more accurate (but still mocked) testing of anything that has conditional treatment of implementers/providers of IBridge. * CHANGE bridgedb.test.util.DummyBridge and DummyMaliciousBridge to declare that they both implement the IBridge interface. Conflicts: lib/bridgedb/test/util.py --- lib/bridgedb/test/util.py |5 + 1 file changed, 5 insertions(+) diff --git a/lib/bridgedb/test/util.py b/lib/bridgedb/test/util.py index 500bbb8..0f1e0f9 100644 --- a/lib/bridgedb/test/util.py +++ b/lib/bridgedb/test/util.py @@ -25,8 +25,11 @@ from functools import wraps from twisted.trial import unittest from bridgedb import util as bdbutil +from bridgedb.bridges import IBridge from bridgedb.parse.addr import isIPAddress +from zope.interface import implementer + def fileCheckDecorator(func): """Method decorator for a t.t.unittest.TestCase test_* method. @@ -248,6 +251,7 @@ class Benchmarker(object): print("Benchmark: %12fms %12fs" % (self.milliseconds, self.seconds)) +@implementer(IBridge) class DummyBridge(object): """A mock :class:`bridgedb.bridges.Bridge` which only supports a mocked ``getBridgeLine`` method.""" @@ -284,6 +288,7 @@ class DummyBridge(object): return " ".join([item for item in line]) +@implementer(IBridge) class DummyMaliciousBridge(DummyBridge): """A mock :class:`bridgedb.Bridges.Bridge` which only supports a mocked ``getConfigLine`` method and which maliciously insert an additional fake ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Add a utility for registering interface adapter classes.
commit ab5c6b01c2c0dc461d45899105a0e6892e682ef7 Author: Isis Lovecruft Date: Mon May 11 02:01:45 2015 + Add a utility for registering interface adapter classes. --- lib/bridgedb/util.py | 16 1 file changed, 16 insertions(+) diff --git a/lib/bridgedb/util.py b/lib/bridgedb/util.py index 7f906d7..f15e08b 100644 --- a/lib/bridgedb/util.py +++ b/lib/bridgedb/util.py @@ -19,6 +19,8 @@ import logging.config import logging.handlers import os +from twisted.python import components + def _getLogHandlers(logToFile=True, logToStderr=True): """Get the appropriate list of log handlers. @@ -245,6 +247,20 @@ def replaceControlChars(text, replacement=None, encoding="utf-8"): return str(escaped) +def registerAdapter(adapter, adapted, interface): +"""Register a Zope interface adapter for global use. + +See :api:`twisted.python.components.registerAdapter` and the Twisted +Matrix Labs `howto documentation for components`_. + +.. howto documentation for components: +https://twistedmatrix.com/documents/current/core/howto/components.html +""" +try: +components.registerAdapter(adapter, adapted, interface) +except ValueError: # An adapter class was already registered +pass + class JustifiedLogFormatter(logging.Formatter): """A logging formatter which pretty prints thread and calling function ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Merge branch 'hotfix/0.3.2-remove-lib-dir' into develop
commit 8bf4f5f995f0592a0c85347b440fa393a6f7a8e3 Merge: 4ebb784 6d309ca Author: Isis Lovecruft Date: Thu Jun 25 06:43:27 2015 + Merge branch 'hotfix/0.3.2-remove-lib-dir' into develop .gitattributes |2 +- .pylintrc |2 +- Makefile | 10 +- bridgedb/Bridges.py| 684 bridgedb/Bucket.py | 288 bridgedb/Main.py | 507 ++ bridgedb/Stability.py | 295 bridgedb/Storage.py| 466 + bridgedb/__init__.py | 17 + bridgedb/_langs.py | 26 + bridgedb/_version.py | 197 +++ bridgedb/bridgerequest.py | 206 +++ bridgedb/bridges.py| 1769 +++ bridgedb/captcha.py| 392 + bridgedb/configure.py | 157 ++ bridgedb/crypto.py | 450 + bridgedb/distribute.py | 275 +++ bridgedb/email/__init__.py |1 + bridgedb/email/autoresponder.py| 704 bridgedb/email/distributor.py | 219 +++ bridgedb/email/dkim.py | 73 + bridgedb/email/request.py | 171 ++ bridgedb/email/server.py | 496 ++ bridgedb/email/templates.py| 200 +++ bridgedb/filters.py| 238 +++ bridgedb/geo.py| 82 + bridgedb/https/__init__.py |1 + bridgedb/https/distributor.py | 328 bridgedb/https/request.py | 143 ++ bridgedb/https/server.py | 905 ++ .../https/templates/assets/css/bootstrap.min.css |7 + bridgedb/https/templates/assets/css/custom.css | 158 ++ .../templates/assets/css/font-awesome-ie7.min.css | 384 + .../templates/assets/css/font-awesome.min.css | 403 + bridgedb/https/templates/assets/css/main.css | 24 + .../templates/assets/font/fontawesome-webfont.eot | Bin 0 -> 37405 bytes .../templates/assets/font/fontawesome-webfont.svg | 399 + .../templates/assets/font/fontawesome-webfont.ttf | Bin 0 -> 79076 bytes .../templates/assets/font/fontawesome-webfont.woff | Bin 0 -> 43572 bytes .../https/templates/assets/font/lato-bold.woff | Bin 0 -> 46160 bytes .../https/templates/assets/font/lato-italic.woff | Bin 0 -> 47168 bytes .../https/templates/assets/font/lato-regular.woff | Bin 0 -> 46108 bytes bridgedb/https/templates/assets/tor-roots-blue.svg | 95 + bridgedb/https/templates/assets/tor.svg|6 + bridgedb/https/templates/base.html | 108 ++ bridgedb/https/templates/bridges.html | 203 +++ bridgedb/https/templates/captcha.html | 63 + bridgedb/https/templates/howto.html| 39 + bridgedb/https/templates/index.html| 43 + bridgedb/https/templates/options.html | 164 ++ bridgedb/https/templates/robots.txt| 1079 bridgedb/i18n/ar/LC_MESSAGES/bridgedb.po | 368 bridgedb/i18n/az/LC_MESSAGES/bridgedb.po | 357 bridgedb/i18n/bg/LC_MESSAGES/bridgedb.po | 357 bridgedb/i18n/ca/LC_MESSAGES/bridgedb.po | 386 + bridgedb/i18n/cs/LC_MESSAGES/bridgedb.po | 363 bridgedb/i18n/cy/LC_MESSAGES/bridgedb.po | 102 ++ bridgedb/i18n/da/LC_MESSAGES/bridgedb.po | 384 + bridgedb/i18n/de/LC_MESSAGES/bridgedb.po | 389 + bridgedb/i18n/el/LC_MESSAGES/bridgedb.po | 364 bridgedb/i18n/en/LC_MESSAGES/bridgedb.po | 433 + bridgedb/i18n/en_GB/LC_MESSAGES/bridgedb.po| 382 bridgedb/i18n/en_US/LC_MESSAGES/bridgedb.po| 433 + bridgedb/i18n/eo/LC_MESSAGES/bridgedb.po | 359 bridgedb/i18n/es/LC_MESSAGES/bridgedb.po | 388 + bridgedb/i18n/es_CL/LC_MESSAGES/bridgedb.po| 102 ++ bridgedb/i18n/eu/LC_MESSAGES/bridgedb.po | 101 ++ bridgedb/i18n/fa/LC_MESSAGES/bridgedb.po | 387 + bridgedb/i18n/fi/LC_MESSAGES/bridgedb.po | 386 + bridgedb/i18n/fr/LC_MESSAGES/bridgedb.po | 393 + bridgedb/i18n/fr_CA/LC_MESSAGES/bridgedb.po| 383 bridgedb/i18n/gl/LC_MESSAGES/bridgedb.po | 101 ++ bridgedb/i18n/he/LC_MESSAGES/bridgedb.po | 105 ++ bridgedb/i18n/hr_HR/LC_MESSAGES/bridgedb.po| 384 + bridgedb/i1
[tor-commits] [bridgedb/develop] Add several additional tests for bridgedb.email.distributor.
commit bb5b29dd19f32fb62d01a4d7ffb65b34493645e4 Author: Isis Lovecruft Date: Wed Apr 22 02:58:31 2015 + Add several additional tests for bridgedb.email.distributor. --- lib/bridgedb/email/distributor.py | 12 +- lib/bridgedb/test/test_email_distributor.py | 177 ++- 2 files changed, 182 insertions(+), 7 deletions(-) diff --git a/lib/bridgedb/email/distributor.py b/lib/bridgedb/email/distributor.py index b73c082..d8ea9bf 100644 --- a/lib/bridgedb/email/distributor.py +++ b/lib/bridgedb/email/distributor.py @@ -101,7 +101,7 @@ class EmailDistributor(Distributor): def bridgesPerResponse(self, hashring=None): return super(EmailDistributor, self).bridgesPerResponse(hashring) -def getBridges(self, bridgeRequest, interval): +def getBridges(self, bridgeRequest, interval, clock=None): """Return a list of bridges to give to a user. .. hint:: All checks on the email address (which should be stored in @@ -119,6 +119,13 @@ class EmailDistributor(Distributor): address. :param interval: The time period when we got this request. This can be any string, so long as it changes with every period. +:type clock: :api:`twisted.internet.task.Clock` +:param clock: If given, use the clock to ask what time it is, rather +than :api:`time.time`. This should likely only be used for +testing. +:rtype: list or ``None`` +:returns: A list of :class:`~bridgedb.bridges.Bridges` for the +``bridgeRequest.client``, if allowed. Otherwise, returns ``None``. """ if (not bridgeRequest.client) or (bridgeRequest.client == 'default'): raise addr.BadEmail( @@ -129,6 +136,9 @@ class EmailDistributor(Distributor): now = time.time() +if clock: +now = clock.seconds() + with bridgedb.Storage.getDB() as db: wasWarned = db.getWarnedEmail(bridgeRequest.client) lastSaw = db.getEmailTime(bridgeRequest.client) diff --git a/lib/bridgedb/test/test_email_distributor.py b/lib/bridgedb/test/test_email_distributor.py index 96eb306..b4d88b2 100644 --- a/lib/bridgedb/test/test_email_distributor.py +++ b/lib/bridgedb/test/test_email_distributor.py @@ -15,6 +15,7 @@ import logging import tempfile import os +from twisted.internet.task import Clock from twisted.trial import unittest import bridgedb.Storage @@ -24,6 +25,7 @@ from bridgedb.email.distributor import EmailDistributor from bridgedb.email.distributor import IgnoreEmail from bridgedb.email.distributor import TooSoonEmail from bridgedb.email.request import EmailBridgeRequest +from bridgedb.parse.addr import BadEmail from bridgedb.parse.addr import UnsupportedDomain from bridgedb.parse.addr import normalizeEmail from bridgedb.test.util import generateFakeBridges @@ -37,13 +39,14 @@ BRIDGES = generateFakeBridges() class EmailDistributorTests(unittest.TestCase): """Tests for :class:`bridgedb.email.distributor.EmailDistributor`.""" +# Fail any tests which take longer than 15 seconds. +timeout = 15 + def setUp(self): -self.fd, self.fname = tempfile.mkstemp() +self.fd, self.fname = tempfile.mkstemp(suffix=".sqlite", dir=os.getcwd()) bridgedb.Storage.initializeDBLock() self.db = bridgedb.Storage.openDatabase(self.fname) bridgedb.Storage.setDBFilename(self.fname) -self.cur = self.db.cursor() -self.db.close() self.bridges = BRIDGES self.key = 'aQpeOFIj8q20s98awfoiq23rpOIjFaqpEWFoij1X' @@ -68,7 +71,68 @@ class EmailDistributorTests(unittest.TestCase): bridgeRequest.generateFilters() return bridgeRequest -def test_EmailDistributor_rate_limit(self): +def test_EmailDistributor_getBridges_default_client(self): +"""If EmailBridgeRequest.client was not set, then getBridges() should +raise a bridgedb.parse.addr.BadEmail exception. +""" +dist = EmailDistributor(self.key, self.domainmap, self.domainrules) +[dist.hashring.insert(bridge) for bridge in self.bridges] + +# The "default" client is literally the string "default", see +# bridgedb.bridgerequest.BridgeRequestBase. +bridgeRequest = self.makeClientRequest('default') + +self.assertRaises(BadEmail, dist.getBridges, bridgeRequest, 1) + +def test_EmailDistributor_getBridges_with_whitelist(self): +"""If an email address is in the whitelist, it should get a response +every time it asks (i.e. no rate-limiting). +""" +# The whitelist should be in the form {EMAIL: GPG_FINGERPRINT} +whitelist = {'wh...@list.ed': '0123456789ABCDEF0123456789ABCDEF01234567'} +dist = EmailDistributor(self.key, self.domainmap, self.domainrules, +whitelist=whitelist) +[dist.hashring.insert(bridge) for bridge in self.
[tor-commits] [bridgedb/develop] Add a filter for unblocked pluggable transports.
commit 5088163284bd512082f113fe84f27f7af86973b8 Author: Isis Lovecruft Date: Tue Apr 21 03:08:03 2015 + Add a filter for unblocked pluggable transports. * ADD Filters.filterBridgesByUnblockedTransport(). * CHANGE bridgerequest.BridgeRequestBase.generateFilters() to handle requests for unblocked bridges with pluggable transports. --- lib/bridgedb/Filters.py | 61 + lib/bridgedb/bridgerequest.py | 25 +++-- 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/lib/bridgedb/Filters.py b/lib/bridgedb/Filters.py index eb7db4e..d0d65e8 100644 --- a/lib/bridgedb/Filters.py +++ b/lib/bridgedb/Filters.py @@ -90,6 +90,67 @@ def filterBridgesByTransport(methodname, addressClass=None): funcs[ruleset] = _filterByTransport return _filterByTransport +def filterBridgesByUnblockedTransport(methodname, countryCode=None, addressClass=None): +"""Return a filter function for :class:`~bridgedb.bridges.Bridge`s. + +The returned filter function should be called on a +:class:`~bridgedb.bridges.Bridge`. It returns ``True`` if the ``Bridge`` +has a :class:`~bridgedb.bridges.PluggableTransport` such that: + + 1. The :data:`~bridge.bridges.PluggableTransport.methodname` matches + **methodname**, + + 2. The :data:`~bridgedb.bridges.PluggableTransport.address`` is an + instance of **addressClass**, and isn't known to be blocked in + **countryCode**. + +:param str methodname: A Pluggable Transport +:data:`~bridge.bridges.PluggableTransport.methodname`. +:type countryCode: str or ``None`` +:param countryCode: A two-letter country code which the filtered +:class:`PluggableTransport`s should not be blocked in. +:type addressClass: ``ipaddr.IPAddress`` +:param addressClass: The IP version that the ``Bridge``'s +``PluggableTransport`` +:data:`~bridgedb.bridges.PluggableTransport.address`` should have. +:rtype: callable +:returns: A filter function for :class:`~bridgedb.bridges.Bridge`s. +""" +if not countryCode: +return filterBridgesByTransport(methodname, addressClass) + +if not ((addressClass is IPv4Address) or (addressClass is IPv6Address)): +addressClass = IPv4Address + +# Ignore case +methodname = methodname.lower() +countryCode = countryCode.lower() + +ruleset = frozenset([methodname, countryCode, addressClass.__name__]) +try: +return funcs[ruleset] +except KeyError: +def _filterByUnblockedTransport(bridge): +# Since bridge.transportIsBlockedIn() will return True if the +# bridge has that type of transport AND that transport is blocked, +# we can "fail fast" here by doing this faster check before +# iterating over all the transports testing for the other +# conditions. +if bridge.transportIsBlockedIn(countryCode, methodname): +return False +else: +for transport in bridge.transports: +if (transport.methodname == methodname and +isinstance(transport.address, addressClass)): +return True +return False +_filterByUnblockedTransport.__name__ = ("filterBridgesByUnblockedTransport(%s,%s,%s)" +% (methodname, countryCode, addressClass)) +setattr(_filterByUnblockedTransport, "description", +"transport=%s unblocked=%s" % (methodname, countryCode)) +funcs[ruleset] = _filterByUnblockedTransport +return _filterByUnblockedTransport + def filterBridgesByNotBlockedIn(countryCode): """Return ``True`` if at least one of a bridge's (transport) bridgelines isn't known to be blocked in **countryCode**. diff --git a/lib/bridgedb/bridgerequest.py b/lib/bridgedb/bridgerequest.py index 532558d..b699896 100644 --- a/lib/bridgedb/bridgerequest.py +++ b/lib/bridgedb/bridgerequest.py @@ -171,15 +171,22 @@ class BridgeRequestBase(object): return ptType def generateFilters(self): -if self.addressClass is ipaddr.IPv6Address: -self.addFilter(Filters.filterBridgesByIP6) -else: -self.addFilter(Filters.filterBridgesByIP4) +self.clearFilters() transport = self.justOnePTType() + if transport: -self.clearFilters() -self.addFilter(Filters.filterBridgesByTransport(transport, -self.addressClass)) -for country in self.notBlockedIn: - self.addFilter(Filters.filterBridgesByNotBlockedIn(country.lower())) +if self.notBlockedIn: +for country in self.notBlockedIn: +self.addFilter(Filters.filterBridgesByUnblockedTransport( +transpo
[tor-commits] [bridgedb/develop] Add subring numbers to their names to improve log clarity.
commit aecbe451d65f55e92de3554ef8a17bb858dda3e1 Author: Isis Lovecruft Date: Tue Apr 21 02:47:09 2015 + Add subring numbers to their names to improve log clarity. * CHANGE bridgedb.Filters.filterAssignBridgesToRing() to rename generated filter functions to include the subring number and the total number of subrings, e.g. filter.__name__ = "filterAssignBridgesToRing3of4" * CHANGE bridgedb.Bridges.FilteredBridgeSplitter.addRing() to name subrings based on their number. For example, if an HTTPSDistributor has 3 total subrings and subring 3/3 is for known-proxy users, then the subrings would be named like: - HTTPS-IP4-1of3 - HTTPS-IP4-2of3 - HTTPS-IP4-Proxy - HTTPS-IP6-1of3 - HTTPS-IP6-2of3 - HTTPS-IP6-Proxy --- lib/bridgedb/Bridges.py | 18 +- lib/bridgedb/Filters.py | 10 -- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py index 4b77cdc..507013d 100644 --- a/lib/bridgedb/Bridges.py +++ b/lib/bridgedb/Bridges.py @@ -613,13 +613,21 @@ class FilteredBridgeSplitter(object): filterNames = self.extractFilterNames(ringname) subringName = [self.distributorName] +subringNumber = None for filterName in filterNames: -if filterName != 'filterAssignBridgesToRing': -subringName.append(filterName.strip('filterBridgesBy')) +if filterName.startswith('filterAssignBridgesToRing'): +subringNumber = filterName.lstrip('filterAssignBridgesToRing') +else: +subringName.append(filterName.lstrip('filterBridgesBy')) +if subring.name and 'Proxy' in subring.name: +subringName.append('Proxy') +elif subringNumber: +subringName.append(subringNumber) subringName = '-'.join([x for x in subringName]) subring.setName(subringName) -logging.info("Adding subring to %s hashring..." % subring.name) +logging.info("Adding %s subring %s to the %s Distributor's hashring..." % + (subring.name, subringNumber, self.distributorName)) logging.info(" Subring filters: %s" % filterNames) #TODO: drop LRU ring if len(self.filterRings) > self.max_cached_rings @@ -631,8 +639,8 @@ class FilteredBridgeSplitter(object): if isinstance(bridge, Bridge) and filterFn(bridge): subring.insert(bridge) inserted += 1 -logging.info("Bridges inserted into %s subring: %d" - % (subring.name, inserted)) +logging.info("Bridges inserted into %s subring %s: %d" + % (subring.name, subringNumber, inserted)) return True diff --git a/lib/bridgedb/Filters.py b/lib/bridgedb/Filters.py index fb0197b..cb5e782 100644 --- a/lib/bridgedb/Filters.py +++ b/lib/bridgedb/Filters.py @@ -8,11 +8,9 @@ import logging funcs = {} def filterAssignBridgesToRing(hmac, numRings, assignedRing): -#XXX: ruleset should have a key unique to this function -# ruleset ensures that the same -logging.debug("Creating a filter for assigning bridges to hashrings...") +logging.debug(("Creating a filter for assigning bridges to subhashring " + "%s-of-%s...") % (assignedRing, numRings)) ruleset = frozenset([hmac, numRings, assignedRing]) - try: return funcs[ruleset] except KeyError: @@ -24,8 +22,8 @@ def filterAssignBridgesToRing(hmac, numRings, assignedRing): if which == assignedRing: return True return False -_assignBridgesToRing.__name__ = ("filterAssignBridgesToRing(%s, %s, %s)" - % (hmac, numRings, assignedRing)) +_assignBridgesToRing.__name__ = ("filterAssignBridgesToRing%sof%s" + % (assignedRing, numRings)) # XXX The `description` attribute must contain an `=`, or else # dumpAssignments() will not work correctly. setattr(_assignBridgesToRing, "description", "ring=%d" % assignedRing) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Remove dumpAssignments() for all Distributors.
commit 69becd92ceb3b55777acddbe4734f7aa912cb425 Author: Isis Lovecruft Date: Sun Apr 19 04:49:24 2015 + Remove dumpAssignments() for all Distributors. These methods were never used. Hashrings dump the bridges assigned to them. --- lib/bridgedb/Dist.py |6 -- 1 file changed, 6 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index e149d17..fe6b8da 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -346,9 +346,6 @@ class HTTPSDistributor(Distributor): return answer -def dumpAssignments(self, f, description=""): -self.hashring.dumpAssignments(f, description) - class EmailBasedDistributor(Distributor): """Object that hands out bridges based on the email address of an incoming @@ -483,9 +480,6 @@ class EmailBasedDistributor(Distributor): else: db.commit() -def dumpAssignments(self, f, description=""): -self.hashring.dumpAssignments(f, description) - def prepopulateRings(self): # populate all rings (for dumping assignments and testing) for filterFn in [filterBridgesByIP4, filterBridgesByIP6]: ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Remove Bridges.BridgeHolder class.
commit 346d321fa4f78626c49cd4ff6d82a346267f6c0c Author: Isis Lovecruft Date: Sun Apr 19 03:25:11 2015 + Remove Bridges.BridgeHolder class. It wasn't a real metaclass, base class, or interface; its methods were never used; it didn't provide any decent documentation; not everything which inherited from it used its methods; nothing called super() for it, or otherwise called methods on it. Totally useless. * REMOVE bridgedb.Bridges.BridgeHolder class. * CHANGE everything which previously inherited from BridgeHolder to simply inherit from object instead. --- lib/bridgedb/Bridges.py| 63 lib/bridgedb/Main.py |4 +-- lib/bridgedb/persistent.py |3 +- lib/bridgedb/test/test_Main.py |6 ++-- 4 files changed, 32 insertions(+), 44 deletions(-) diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py index 5742794..1a06dd8 100644 --- a/lib/bridgedb/Bridges.py +++ b/lib/bridgedb/Bridges.py @@ -39,18 +39,6 @@ DIGEST_LEN = 20 PORTSPEC_LEN = 16 -class BridgeHolder(object): -"""Abstract base class for all classes that hold bridges.""" -def insert(self, bridge): -raise NotImplementedError - -def clear(self): -pass - -def dumpAssignments(self, f, description=""): -pass - - class BridgeRingParameters(object): """Store validated settings on minimum number of Bridges with certain attributes which should be included in any generated subring of a @@ -99,7 +87,8 @@ class BridgeRingParameters(object): self.needPorts = needPorts[:] self.needFlags = [(flag.lower(), count) for flag, count in needFlags[:]] -class BridgeRing(BridgeHolder): + +class BridgeRing(object): """Arranges bridges into a hashring based on an hmac function.""" def __init__(self, key, answerParameters=None): @@ -333,15 +322,13 @@ class BridgeRing(BridgeHolder): f.write("%s %s\n" % (b.fingerprint, " ".join(desc).strip())) -class FixedBridgeSplitter(BridgeHolder): -"""A bridgeholder that splits bridges up based on an hmac and assigns - them to several sub-bridgeholders with equal probability. +class FixedBridgeSplitter(object): +"""Splits bridges up based on an HMAC and assigns them to one of several +subhashrings with equal probability. """ def __init__(self, key, rings): self.hmac = getHMACFunc(key, hex=True) self.rings = rings[:] -for r in self.rings: -assert(isinstance(r, BridgeHolder)) def insert(self, bridge): # Grab the first 4 bytes @@ -366,7 +353,7 @@ class FixedBridgeSplitter(BridgeHolder): """Write all bridges assigned to this hashring to ``filename``. :param string description: If given, include a description next to the -index number of the ring from :attr:`FilteredBridgeHolder.rings` +index number of the ring from :attr:`FilteredBridgeSplitter.rings` the following bridges were assigned to. For example, if the description is ``"IPv6 obfs2 bridges"`` the line would read: ``"IPv6 obfs2 bridges ring=3"``. @@ -374,7 +361,8 @@ class FixedBridgeSplitter(BridgeHolder): for index, ring in zip(xrange(len(self.rings)), self.rings): ring.dumpAssignments(filename, "%s ring=%s" % (description, index)) -class UnallocatedHolder(BridgeHolder): + +class UnallocatedHolder(object): """A pseudo-bridgeholder that ignores its bridges and leaves them unassigned. """ @@ -407,10 +395,11 @@ class UnallocatedHolder(BridgeHolder): continue f.write("%s %s\n" % (bridge.hex_key, " ".join(desc).strip())) -class BridgeSplitter(BridgeHolder): -"""A BridgeHolder that splits incoming bridges up based on an hmac, - and assigns them to sub-bridgeholders with different probabilities. - Bridge-to-bridgeholder associations are recorded in a store. + +class BridgeSplitter(object): +"""Splits incoming bridges up based on an HMAC, and assigns them to +sub-bridgeholders with different probabilities. Bridge ââ BridgeSplitter +associations are recorded in a store. """ def __init__(self, key): self.hmac = getHMACFunc(key, hex=True) @@ -428,12 +417,13 @@ class BridgeSplitter(BridgeHolder): return n def addRing(self, ring, ringname, p=1): -"""Add a new bridgeholder. - ring -- the bridgeholder to add. - ringname -- a string representing the bridgeholder. This is used - to record which bridges have been assigned where in the store. - p -- the relative proportion of bridges to assign to this - bridgeholder. +"""Add a new subring. + +:param ring: The subring to add. +:param str ringname: This is used to record which bridges have been +assigned where in t
[bridgedb/develop] Change BridgeRequestBase.addressClass → BridgeRequestBase.ipVersion.
commit 9c34acd384a57f23f451142978b0fdbc4694dc72 Author: Isis Lovecruft Date: Mon May 11 01:04:42 2015 + Change BridgeRequestBase.addressClass â BridgeRequestBase.ipVersion. Passing an integer around both requires less memory, and makes the IP version filters in bridgedb.filters run faster (since they no longer need to use isinstance()). * CHANGE bridgedb.bridges.Bridge to use ipVersion when working with BridgeRequestBase. --- lib/bridgedb/bridgerequest.py | 57 ++- lib/bridgedb/bridges.py | 12 +++ lib/bridgedb/filters.py |4 +-- lib/bridgedb/test/test_email_request.py | 16 - lib/bridgedb/test/util.py |2 +- 5 files changed, 51 insertions(+), 40 deletions(-) diff --git a/lib/bridgedb/bridgerequest.py b/lib/bridgedb/bridgerequest.py index 2ded7b3..1266145 100644 --- a/lib/bridgedb/bridgerequest.py +++ b/lib/bridgedb/bridgerequest.py @@ -27,10 +27,10 @@ from bridgedb.filters import byTransport class IRequestBridges(Interface): """Interface specification of client options for requested bridges.""" -addressClass = Attribute( -"The IP version of bridge addresses to distribute to the client.") filters = Attribute( "A list of callables used to filter bridges from a hashring.") +ipVersion = Attribute( +"The IP version of bridge addresses to distribute to the client.") transports = Attribute( "A list of strings of Pluggable Transport types requested.") notBlockedIn = Attribute( @@ -54,7 +54,7 @@ class IRequestBridges(Interface): def generateFilters(): """Build the list of callables, ``filters``, according to the current contents of the lists of ``transports``, ``notBlockedIn``, and the -``addressClass``. +``ipVersion``. """ def getHashringPlacement(): @@ -68,10 +68,10 @@ class IRequestBridges(Interface): """Determine if the request is ``valid`` according to some parameters.""" def withIPv4(): -"""Set the ``addressClass`` to IPv4.""" +"""Set the ``ipVersion`` to IPv4.""" def withIPv6(): -"""Set the ``addressClass`` to IPv6.""" +"""Set the ``ipVersion`` to IPv6.""" def withPluggableTransportType(typeOfPT): """Add this **typeOfPT** to the list of requested ``transports``.""" @@ -87,13 +87,8 @@ class BridgeRequestBase(object): implements(IRequestBridges) -def __init__(self, addressClass=None): -#: (:class:`ipaddr.IPv4Address` or :class:`ipaddr.IPv6Address`) The IP -#: version of bridge addresses to distribute to the client. -self.addressClass = addressClass -if not ((self.addressClass is ipaddr.IPv4Address) or -(self.addressClass is ipaddr.IPv6Address)): -self.addressClass = ipaddr.IPv4Address +def __init__(self, ipVersion=None): +self.ipVersion = ipVersion #: (list) A list of callables used to filter bridges from a hashring. self.filters = list() #: (list) A list of strings of Pluggable Transport types requested. @@ -110,6 +105,26 @@ class BridgeRequestBase(object): #: (bool) Should be ``True`` if the client's request was valid. self.valid = False +@property +def ipVersion(self): +"""The IP version of bridge addresses to distribute to the client. + +:rtype: int +:returns: Either ``4`` or ``6``. +""" +return self._ipVersion + +@ipVersion.setter +def ipVersion(self, ipVersion): +"""The IP version of bridge addresses to distribute to the client. + +:param int ipVersion: The IP address version for the bridge lines we +should distribute in response to this client request. +""" +if not ipVersion in (4, 6): +ipVersion = 4 +self._ipVersion = ipVersion + def getHashringPlacement(self, key, client=None): """Create an HMAC of some **client** info using a **key**. @@ -145,10 +160,10 @@ class BridgeRequestBase(object): return self.valid def withIPv4(self): -self.addressClass = ipaddr.IPv4Address +self.ipVersion = 4 def withIPv6(self): -self.addressClass = ipaddr.IPv6Address +self.ipVersion = 6 def withoutBlockInCountry(self, country): self.notBlockedIn.append(country.lower()) @@ -175,21 +190,17 @@ class BridgeRequestBase(object): self.clearFilters() pt = self.justOnePTType() -msg = ("Adding a filter to %s for %s for IPv%s" - % (self.__class__.__name__, self.client, self.addressClass)) - -self.ipVersion = 4 -if self.addressClass is ipaddr.IPv6Address: -self.ipVersion = 6 +msg = ("Adding a filter to %s for %s for IPv%d" + % (self.__class__.__name__, self.client, s
[bridgedb/develop] Move bridgedb.Dist.EmailBasedDistributor → bridgedb.email.distributor.
commit 55f36f523dae951e2c0e57cdfdc84e3a78ba7cbe Author: Isis Lovecruft Date: Tue Apr 21 21:41:20 2015 + Move bridgedb.Dist.EmailBasedDistributor â bridgedb.email.distributor. --- doc/sphinx/source/bridgedb.Dist.rst |8 - doc/sphinx/source/bridgedb.email.rst |1 + doc/sphinx/source/bridgedb.rst|1 - doc/sphinx/source/conf.py |2 +- lib/bridgedb/Dist.py | 186 -- lib/bridgedb/Main.py |9 +- lib/bridgedb/email/autoresponder.py |8 +- lib/bridgedb/email/distributor.py | 209 + lib/bridgedb/email/request.py |6 +- lib/bridgedb/email/server.py |4 +- lib/bridgedb/email/templates.py |2 +- lib/bridgedb/parse/addr.py|7 +- lib/bridgedb/persistent.py|4 +- lib/bridgedb/test/email_helpers.py| 14 +- lib/bridgedb/test/legacy_Tests.py | 43 + lib/bridgedb/test/test_email_autoresponder.py |2 +- lib/bridgedb/test/test_email_distributor.py | 93 +++ lib/bridgedb/test/test_email_server.py|6 +- 18 files changed, 340 insertions(+), 265 deletions(-) diff --git a/doc/sphinx/source/bridgedb.Dist.rst b/doc/sphinx/source/bridgedb.Dist.rst deleted file mode 100644 index 995a7ac..000 --- a/doc/sphinx/source/bridgedb.Dist.rst +++ /dev/null @@ -1,8 +0,0 @@ -bridgedb.Dist - - -.. automodule:: bridgedb.Dist -:members: -:undoc-members: -:private-members: -:show-inheritance: diff --git a/doc/sphinx/source/bridgedb.email.rst b/doc/sphinx/source/bridgedb.email.rst index ba9b4a9..020b614 100644 --- a/doc/sphinx/source/bridgedb.email.rst +++ b/doc/sphinx/source/bridgedb.email.rst @@ -8,6 +8,7 @@ bridgedb.email .. automodule:: bridgedb.email.__init__ .. automodule:: bridgedb.email.autoresponder +.. automodule:: bridgedb.email.distributor .. automodule:: bridgedb.email.dkim .. automodule:: bridgedb.email.request .. automodule:: bridgedb.email.server diff --git a/doc/sphinx/source/bridgedb.rst b/doc/sphinx/source/bridgedb.rst index 7b1fef7..207313c 100644 --- a/doc/sphinx/source/bridgedb.rst +++ b/doc/sphinx/source/bridgedb.rst @@ -13,7 +13,6 @@ BridgeDB Package and Module Documentation bridgedb.captcha bridgedb.configure bridgedb.crypto -bridgedb.Dist bridgedb.email bridgedb.filters bridgedb.geo diff --git a/doc/sphinx/source/conf.py b/doc/sphinx/source/conf.py index 5038abb..cab614f 100644 --- a/doc/sphinx/source/conf.py +++ b/doc/sphinx/source/conf.py @@ -33,9 +33,9 @@ import bridgedb.captcha import bridgedb.Bridges import bridgedb.Bucket import bridgedb.crypto -import bridgedb.Dist import bridgedb.email import bridgedb.email.autoresponder +import bridgedb.email.distributor import bridgedb.email.dkim import bridgedb.email.request import bridgedb.email.server diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py deleted file mode 100644 index 1be705f..000 --- a/lib/bridgedb/Dist.py +++ /dev/null @@ -1,186 +0,0 @@ -# -*- coding: utf-8 ; test-case-name: bridgedb.test.test_Dist -*- -# -# This file is part of BridgeDB, a Tor bridge distribution system. -# -# :authors: Nick Mathewson -# Isis Lovecruft 0xA3ADB67A2CDB8B35 -# Matthew Finkel 0x017DD169EA793BE2 -# :copyright: (c) 2013-2015, Isis Lovecruft -# (c) 2013-2015, Matthew Finkel -# (c) 2007-2015, The Tor Project, Inc. -# :license: 3-Clause BSD, see LICENSE for licensing information - -"""This module has functions to decide which bridges to hand out to whom.""" - -import logging -import time - -import bridgedb.Storage - -from bridgedb.Bridges import BridgeRing -from bridgedb.Bridges import FilteredBridgeSplitter -from bridgedb.crypto import getHMAC -from bridgedb.crypto import getHMACFunc -from bridgedb.distribute import Distributor -from bridgedb.filters import byFilters -from bridgedb.filters import byIPv4 -from bridgedb.filters import byIPv6 -from bridgedb.filters import bySubring -from bridgedb.parse import addr - - -MAX_EMAIL_RATE = 3*3600 - -class IgnoreEmail(addr.BadEmail): -"""Raised when we get requests from this address after rate warning.""" - -class TooSoonEmail(addr.BadEmail): -"""Raised when we got a request from this address too recently.""" - -class EmailRequestedHelp(Exception): -"""Raised when a client has emailed requesting help.""" - -class EmailRequestedKey(Exception): -"""Raised when an incoming email requested a copy of our GnuPG keys.""" - - -class EmailBasedDistributor(Distributor): -"""Object that hands out bridges based on the email address of an incoming -request and the current time period. - -:type hashring: :class:`~bridgedb.Bridges.BridgeRing` -:ivar hashring: A hashring to hold all the bridges we hand out. -""" -
[tor-commits] [bridgedb/develop] Rewrite testDistWithProxies() in legacy_Tests.
commit dcafe58630f9048b7829184675a9a93deda2f0a3 Author: Isis Lovecruft Date: Sun Apr 19 05:43:39 2015 + Rewrite testDistWithProxies() in legacy_Tests. --- lib/bridgedb/test/legacy_Tests.py | 21 - lib/bridgedb/test/test_Dist.py| 24 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/lib/bridgedb/test/legacy_Tests.py b/lib/bridgedb/test/legacy_Tests.py index fd6a739..85ba722 100644 --- a/lib/bridgedb/test/legacy_Tests.py +++ b/lib/bridgedb/test/legacy_Tests.py @@ -185,27 +185,6 @@ class EmailBridgeDistTests(unittest.TestCase): class IPBridgeDistTests(unittest.TestCase): -def testDistWithProxies(self): -d = bridgedb.Dist.HTTPSDistributor(3, "Foo", [RhymesWith255ProxySet()]) -for _ in xrange(256): -d.insert(fakeBridge()) - -for _ in xrange(256): -# Make sure that the ProxySets do not overlap -f = lambda: ".".join([str(random.randrange(1,255)) for _ in xrange(4)]) -g = lambda: ".".join([str(random.randrange(1,255)) for _ in xrange(3)] + ['255']) -n = d.getBridges(g(), "x") -n2 = d.getBridges(f(), "x") - -assert(len(n) > 0) -assert(len(n2) > 0) - -for b in n: -assert (b not in n2) - -for b in n2: -assert (b not in n) - #XXX: #6175 breaks this test! #def testDistWithPortRestrictions(self): #param = bridgedb.Bridges.BridgeRingParameters(needPorts=[(443, 1)]) diff --git a/lib/bridgedb/test/test_Dist.py b/lib/bridgedb/test/test_Dist.py index 23a6492..18b3e79 100644 --- a/lib/bridgedb/test/test_Dist.py +++ b/lib/bridgedb/test/test_Dist.py @@ -243,6 +243,30 @@ class HTTPSDistributorTests(unittest.TestCase): self.assertNotIn(b.fingerprint, blockedIR) self.assertGreater(len(bridges), 0) +def test_HTTPSDistributor_getBridges_with_proxy_and_nonproxy_users(self): +"""An HTTPSDistributor should give separate bridges to proxy users.""" +proxies = ProxySet(['.'.join(['1.1.1', str(x)]) for x in range(1, 256)]) +dist = Dist.HTTPSDistributor(3, self.key, proxies) +[dist.insert(bridge) for bridge in self.bridges] + +for _ in range(10): +bridgeRequest1 = self.randomClientRequest() +bridgeRequest1.client = '.'.join(['1.1.1', str(random.randrange(1, 255))]) + +bridgeRequest2 = self.randomClientRequest() +bridgeRequest2.client = '.'.join(['9.9.9', str(random.randrange(1, 255))]) + +n1 = dist.getBridges(bridgeRequest1, 1) +n2 = dist.getBridges(bridgeRequest2, 1) + +self.assertGreater(len(n1), 0) +self.assertGreater(len(n2), 0) + +for b in n1: +self.assertNotIn(b, n2) +for b in n2: +self.assertNotIn(b, n1) + def test_HTTPSDistributor_getBridges_same_bridges_to_same_client(self): """The same client asking for bridges from the HTTPSDistributor multiple times in a row should get the same bridges in response each ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Switch to using relative imports for test helpers in test/tests_*.py.
commit 6d309cae1e709e615b592690f1a34369f60fa709 Author: Isis Lovecruft Date: Thu Jun 25 05:47:04 2015 + Switch to using relative imports for test helpers in test/tests_*.py. --- bridgedb/util.py | 48 +- test/email_helpers.py|3 ++- test/https_helpers.py|3 ++- test/legacy_Tests.py | 20 +--- test/test_Tests.py | 37 +++-- test/test_bridgedb.py|4 ++-- test/test_bridges.py |6 ++--- test/test_crypto.py |5 ++-- test/test_email_autoresponder.py |7 +++--- test/test_email_distributor.py |3 ++- test/test_email_server.py|7 +++--- test/test_https.py |4 ++-- test/test_https_distributor.py |7 +++--- test/test_https_server.py| 11 + test/test_parse_descriptors.py |2 +- test/test_smtp.py|4 ++-- test/test_translations.py|2 +- test/util.py |8 +++ 18 files changed, 98 insertions(+), 83 deletions(-) diff --git a/bridgedb/util.py b/bridgedb/util.py index f15e08b..4c558c4 100644 --- a/bridgedb/util.py +++ b/bridgedb/util.py @@ -153,6 +153,7 @@ def levenshteinDistance(s1, s2, len1=None, len2=None, the number of characters which must be changed in **s1** to make it identical to **s2**. +>>> from bridgedb.util import levenshteinDistance >>> levenshteinDistance('cat', 'cat') 0 >>> levenshteinDistance('cat', 'hat') @@ -188,6 +189,7 @@ def isascii(s): Note that this function differs from the str.is* methods in that it returns True for the empty string, rather than False. +>>> from bridgedb.util import isascii >>> isascii('\x80') False >>> isascii('foo\tbar\rbaz\n') @@ -206,6 +208,7 @@ def isascii_noncontrol(s): Note that this function differs from the str.is* methods in that it returns True for the empty string, rather than False. +>>> from bridgedb.util import isascii_noncontrol >>> isascii_noncontrol('\x80') False >>> isascii_noncontrol('foo\tbar\rbaz\n') @@ -220,6 +223,7 @@ def isascii_noncontrol(s): def replaceControlChars(text, replacement=None, encoding="utf-8"): """Remove ASCII control characters [0-31, 92, 127]. +>>> from bridgedb.util import replaceControlChars >>> replaceControlChars('foo\n bar\\ baz\r \t\0quux\n') 'foo bar baz quux' >>> replaceControlChars("\bI wonder if I'm outside the quotes now") @@ -344,36 +348,36 @@ class mixin: >>> from bridgedb.util import mixin >>> >>> class ClassA(object): ->>> def sayWhich(self): ->>> print("ClassA.sayWhich() called.") ->>> def doSuperThing(self): ->>> super(ClassA, self).__repr__() ->>> def doThing(self): ->>> print("ClassA is doing a thing.") ->>> +... def sayWhich(self): +... print("ClassA.sayWhich() called.") +... def doSuperThing(self): +... print("%s" % super(ClassA, self)) +... def doThing(self): +... print("ClassA is doing a thing.") +... >>> class ClassB(ClassA): ->>> def sayWhich(self): ->>> print("ClassB.sayWhich() called.") ->>> def doSuperThing(self): ->>> super(ClassB, self).__repr__() ->>> def doOtherThing(self): ->>> print("ClassB is doing something else.") ->>> +... def sayWhich(self): +... print("ClassB.sayWhich() called.") +... def doSuperThing(self): +... print("%s" % super(ClassB, self)) +... def doOtherThing(self): +... print("ClassB is doing something else.") +... >>> class ClassM(mixin): ->>> def sayWhich(self): ->>> print("ClassM.sayWhich() called.") ->>> +... def sayWhich(self): +... print("ClassM.sayWhich() called.") +... >>> ClassM.register(ClassA) >>> >>> class ClassC(ClassM, ClassB): ->>> def sayWhich(self): ->>> super(ClassC, self).sayWhich() ->>> +... def sayWhich(self): +... super(ClassC, self).sayWhich() +... >>> c = ClassC() >>> c.sayWhich() -ClassM.saywhich() called. +ClassM.sayWhich() called. >>> c.doSuperThing() -, NULL> +, > >>> c.doThing() ClassA is doing a thing. >>> c.doOtherThing() diff --git a/test/email_helpers.py b/test/email_helpers.py index 14c86f4..8d7dd49 100644 --- a/test/email_helpers.py +++ b/test/email_helpers.py @@ -18,7 +18,8 @@ from bridgedb.email.distributor import IgnoreEmail from bridgedb.email.distributor import TooSoonEmail from bridgedb.email.server import MailServerContext from bridgedb.schedule import Unscheduled -from bridgedb.test import util + +from . import util EMAIL_DIST = True diff --git a/test/https_
[tor-commits] [bridgedb/develop] Make the @port property common to both PluggableTransports and Bridges.
commit 63bc3924096d0cde3373e37d85ca1101e2fb438e Author: Isis Lovecruft Date: Tue Jun 9 00:08:04 2015 + Make the @port property common to both PluggableTransports and Bridges. Because it seems awkward to require doing type checks in order to know which port a bridge-like thing is listening on. That is, previously, we could access PluggableTransport.port and Bridge.orPort, but *not* Bridge.port. Moving the port @property from the PluggableTransport class to the BridgeAddressBase class (and updating the Bridge.orPort @property to point at the port @property) allows us to access the port property of either one without caring which type it is. In addition to allowing us to forego type checks, this allow allows us to define an interface which essentially says that "a bridge-like thing is a thing which has a fingerprint, address, and a port", which again allows us to generalise code to deal with "bridge-like" things, rather than dealing with a tuple of classes which happen to be considered "bridge-like" at the time of writing. * MOVE the port @property from the PluggableTransport class to the BridgeAddressBase class. * CHANGE the Bridge.orPort @property to point at the new port @property. --- lib/bridgedb/bridges.py | 65 +-- 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/lib/bridgedb/bridges.py b/lib/bridgedb/bridges.py index f56b0e7..5093bef 100644 --- a/lib/bridgedb/bridges.py +++ b/lib/bridgedb/bridges.py @@ -141,12 +141,17 @@ class BridgeAddressBase(object): :type country: str :ivar country: The two-letter GeoIP country code of the :ivar:`address`. + +:type port: int +:ivar port: A integer specifying the port which this :class:`Bridge` +(or :class:`PluggableTransport`) is listening on. """ def __init__(self): self._fingerprint = None self._address = None self._country = None +self._port = None @property def fingerprint(self): @@ -242,6 +247,32 @@ class BridgeAddressBase(object): if self.address: return geo.getCountryCode(self.address) +@property +def port(self): +"""Get the port number which this ``Bridge`` is listening +for incoming client connections on. + +:rtype: int or None +:returns: The port (as an int), if it is known and valid; otherwise, +returns ``None``. +""" +return self._port + +@port.setter +def port(self, value): +"""Store the port number which this ``Bridge`` is listening +for incoming client connections on. + +:param int value: The transport's port. +""" +if isinstance(value, int) and (0 <= value <= 65535): +self._port = value + +@port.deleter +def port(self): +"""Reset this ``Bridge``'s port to ``None``.""" +self._port = None + class PluggableTransport(BridgeAddressBase): """A single instance of a Pluggable Transport (PT) offered by a @@ -314,7 +345,6 @@ class PluggableTransport(BridgeAddressBase): :data:`arguments`. """ super(PluggableTransport, self).__init__() -self._port = None self._methodname = None self._blockedIn = {} @@ -438,32 +468,6 @@ class PluggableTransport(BridgeAddressBase): return False @property -def port(self): -"""Get the port number which this ``PluggableTransport`` is listening -for incoming client connections on. - -:rtype: int or None -:returns: The port (as an int), if it is known and valid; otherwise, -returns ``None``. -""" -return self._port - -@port.setter -def port(self, value): -"""Store the port number which this ``PluggableTransport`` is listening -for incoming client connections on. - -:param int value: The transport's port. -""" -if isinstance(value, int) and (0 <= value <= 65535): -self._port = value - -@port.deleter -def port(self): -"""Reset this ``PluggableTransport``'s port to ``None``.""" -self._port = None - -@property def methodname(self): """Get this :class:`PluggableTransport`'s methodname. @@ -632,7 +636,7 @@ class BridgeBase(BridgeAddressBase): :rtype: int :returns: This Bridge's default ORPort. """ -return self._orPort +return self.port @orPort.setter def orPort(self, value): @@ -640,13 +644,12 @@ class BridgeBase(BridgeAddressBase): :param int value: The Bridge's ORPort. """ -if isinstance(value, int) and (0 <= value <= 65535): -self._orPort = value +self.port = value @orPort.deleter def orPort(self): """Reset this Bridge's ORPort."""
[tor-commits] [bridgedb/develop] Rewrite testDistWithFilterBlockedCountriesAdvanced() in legacy_Tests.
commit 2de77ba16992b8a967bfe68cebc2c17c2b3998fc Author: Isis Lovecruft Date: Tue Apr 21 02:33:08 2015 + Rewrite testDistWithFilterBlockedCountriesAdvanced() in legacy_Tests. --- lib/bridgedb/test/legacy_Tests.py | 41 + lib/bridgedb/test/test_Dist.py| 39 +++ 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/lib/bridgedb/test/legacy_Tests.py b/lib/bridgedb/test/legacy_Tests.py index 2f1da67..95dc34e 100644 --- a/lib/bridgedb/test/legacy_Tests.py +++ b/lib/bridgedb/test/legacy_Tests.py @@ -183,44 +183,6 @@ class EmailBridgeDistTests(unittest.TestCase): {'example.com':'example.com'}, {'example.com':[]}) -class IPBridgeDistTests(unittest.TestCase): - -def testDistWithFilterBlockedCountriesAdvanced(self): -d = bridgedb.Dist.HTTPSDistributor(3, "Foo") -for _ in xrange(250): -d.insert(fakeBridge6(or_addresses=True, transports=True)) -d.insert(fakeBridge(or_addresses=True, transports=True)) - -for b in d.hashring.bridges: -# china blocks some transports -for pt in b.transports: -if random.choice(xrange(2)) > 0: -key = "%s:%s" % (pt.address, pt.port) -b.blockingCountries[key] = set(['cn']) -for address, portlist in b.or_addresses.items(): -# china blocks some transports -for port in portlist: -if random.choice(xrange(2)) > 0: -key = "%s:%s" % (address, port) -b.blockingCountries[key] = set(['cn']) -key = "%s:%s" % (b.ip, b.orport) -b.blockingCountries[key] = set(['cn']) - -# we probably will get at least one bridge back! -# it's pretty unlikely to lose a coin flip 250 times in a row -for i in xrange(5): -b = d.getBridges(randomIPString(), "x", -bridgeFilterRules=[ -filterBridgesByNotBlockedIn("cn"), -filterBridgesByTransport('obfs2'), -]) -try: assert len(b) > 0 -except AssertionError: -print("epic fail") -b = d.getBridges(randomIPString(), "x", bridgeFilterRules=[ -filterBridgesByNotBlockedIn("us")]) -assert len(b) > 0 - class SQLStorageTests(unittest.TestCase): def setUp(self): @@ -450,8 +412,7 @@ def testSuite(): suite = unittest.TestSuite() loader = unittest.TestLoader() -for klass in [IPBridgeDistTests, SQLStorageTests, EmailBridgeDistTests, - BridgeStabilityTests]: +for klass in [SQLStorageTests, EmailBridgeDistTests, BridgeStabilityTests]: suite.addTest(loader.loadTestsFromTestCase(klass)) return suite diff --git a/lib/bridgedb/test/test_Dist.py b/lib/bridgedb/test/test_Dist.py index e8a17e4..85c1b87 100644 --- a/lib/bridgedb/test/test_Dist.py +++ b/lib/bridgedb/test/test_Dist.py @@ -244,6 +244,45 @@ class HTTPSDistributorTests(unittest.TestCase): self.assertNotIn(b.fingerprint, blockedIR) self.assertGreater(len(bridges), 0) +def test_HTTPSDistributor_getBridges_with_varied_blocked_bridges(self): +dist = Dist.HTTPSDistributor(1, self.key) +bridges = self.bridges[:] + +for bridge in bridges: +# Pretend that China blocks all vanilla bridges: +bridge.setBlockedIn('cn', methodname='vanilla') +# Pretend that China blocks all obfs2: +bridge.setBlockedIn('cn', methodname='obfs2') +# Pretend that China blocks some obfs3: +if self.coinFlip(): +bridge.setBlockedIn('cn', methodname='obfs3') + +[dist.insert(bridge) for bridge in bridges] + +for i in xrange(5): +bridgeRequest1 = self.randomClientRequestForNotBlockedIn('cn') +bridgeRequest1.transports.append('obfs2') +bridgeRequest1.generateFilters() +# We shouldn't get any obfs2 bridges, since they're all blocked in +# China: +bridges = dist.getBridges(bridgeRequest1, "faketimestamp") +self.assertEqual(len(bridges), 0) + +bridgeRequest2 = self.randomClientRequestForNotBlockedIn('cn') +bridgeRequest2.transports.append('obfs3') +bridgeRequest2.generateFilters() +# We probably will get at least one bridge back! It's pretty +# unlikely to lose a coin flip 500 times in a row. +bridges = dist.getBridges(bridgeRequest2, "faketimestamp") +self.assertGreater(len(bridges), 0) + +bridgeRequest3 = self.randomClientRequestForNotBlockedIn('nl') +bridgeRequest3.transports.append('obfs3') +bridgeRequest3.generateFilters() +# We
[tor-commits] [bridgedb/develop] Reuse mocked Bridges across various unittests.
commit 7632085c0725e32001e41774564bffe7cb221584 Author: Isis Lovecruft Date: Sun May 10 22:18:26 2015 + Reuse mocked Bridges across various unittests. --- lib/bridgedb/test/util.py |8 1 file changed, 8 insertions(+) diff --git a/lib/bridgedb/test/util.py b/lib/bridgedb/test/util.py index f164aeb..2cddc11 100644 --- a/lib/bridgedb/test/util.py +++ b/lib/bridgedb/test/util.py @@ -168,6 +168,8 @@ randomValidIPv4String = valid(randomIPv4String) randomValidIPv6String = valid(randomIPv6String) randomValidIPString = valid(randomIPString) +_FAKE_BRIDGES = [] + def generateFakeBridges(n=500): """Generate a set of **n** :class:`~bridgedb.bridges.Bridges` with random data. @@ -175,6 +177,11 @@ def generateFakeBridges(n=500): from bridgedb.bridges import Bridge from bridgedb.bridges import PluggableTransport +global _FAKE_BRIDGES + +if _FAKE_BRIDGES: +return _FAKE_BRIDGES + bridges = [] for i in range(n): @@ -199,6 +206,7 @@ def generateFakeBridges(n=500): bridge.orAddresses = addrs bridges.append(bridge) +_FAKE_BRIDGES = bridges return bridges ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Remove testDistWithFilterBlockedCountries() from legacy_Tests.
commit e9713d2a58566b761a68544d552ae5e702008a2d Author: Isis Lovecruft Date: Sun Apr 19 05:03:40 2015 + Remove testDistWithFilterBlockedCountries() from legacy_Tests. The functionality tested in testDistWithFilterBlockedCountries() is now tested in test_Dist.test_HTTPSDistributor_with_blocked_bridges() and test_Dist.test_HTTPSDistributor_with_some_blocked_bridges(). --- lib/bridgedb/test/legacy_Tests.py | 26 -- lib/bridgedb/test/test_Dist.py|2 ++ 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/lib/bridgedb/test/legacy_Tests.py b/lib/bridgedb/test/legacy_Tests.py index 4cdcc03..fc4ca5d 100644 --- a/lib/bridgedb/test/legacy_Tests.py +++ b/lib/bridgedb/test/legacy_Tests.py @@ -303,32 +303,6 @@ class IPBridgeDistTests(unittest.TestCase): filterBridgesByIP4, filterBridgesByIP6]) assert len(b) == 0 -def testDistWithFilterBlockedCountries(self): -d = bridgedb.Dist.HTTPSDistributor(3, "Foo") -for _ in xrange(250): -d.insert(fakeBridge6(or_addresses=True)) -d.insert(fakeBridge(or_addresses=True)) - -for b in d.hashring.bridges: -# china blocks all :-( -for pt in b.transports: -key = "%s:%s" % (pt.address, pt.port) -b.blockingCountries[key] = set(['cn']) -for address, portlist in b.or_addresses.items(): -for port in portlist: -key = "%s:%s" % (address, port) -b.blockingCountries[key] = set(['cn']) -key = "%s:%s" % (b.ip, b.orport) -b.blockingCountries[key] = set(['cn']) - -for i in xrange(5): -b = d.getBridges(randomIPv4String(), "x", bridgeFilterRules=[ -filterBridgesByNotBlockedIn("cn")]) -assert len(b) == 0 -b = d.getBridges(randomIPv4String(), "x", bridgeFilterRules=[ -filterBridgesByNotBlockedIn("us")]) -assert len(b) > 0 - def testDistWithFilterBlockedCountriesAdvanced(self): d = bridgedb.Dist.HTTPSDistributor(3, "Foo") for _ in xrange(250): diff --git a/lib/bridgedb/test/test_Dist.py b/lib/bridgedb/test/test_Dist.py index 3de7945..2d93a19 100644 --- a/lib/bridgedb/test/test_Dist.py +++ b/lib/bridgedb/test/test_Dist.py @@ -230,6 +230,7 @@ class HTTPSDistributorTests(unittest.TestCase): bridges = dist.getBridges(clientRequest1, 1) for b in bridges: self.assertFalse(b.isBlockedIn('cn')) +self.assertNotIn(b.fingerprint, blockedCN) # The client *should* have gotten some bridges still. self.assertGreater(len(bridges), 0) @@ -237,4 +238,5 @@ class HTTPSDistributorTests(unittest.TestCase): bridges = dist.getBridges(clientRequest2, 1) for b in bridges: self.assertFalse(b.isBlockedIn('ir')) +self.assertNotIn(b.fingerprint, blockedIR) self.assertGreater(len(bridges), 0) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Rewrite testDistWithFilterIP4() in legacy_Tests.
commit d9dcb7f3d143cfb46f2f1e988da96cf5a5b1b449 Author: Isis Lovecruft Date: Tue Apr 21 23:34:50 2015 + Rewrite testDistWithFilterIP4() in legacy_Tests. --- lib/bridgedb/test/legacy_Tests.py | 16 lib/bridgedb/test/test_Dist.py| 20 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/lib/bridgedb/test/legacy_Tests.py b/lib/bridgedb/test/legacy_Tests.py index 043f09b..9a0c74f 100644 --- a/lib/bridgedb/test/legacy_Tests.py +++ b/lib/bridgedb/test/legacy_Tests.py @@ -252,22 +252,6 @@ class IPBridgeDistTests(unittest.TestCase): assert type(ipaddr.IPAddress(address)) is ipaddr.IPv6Address assert filterBridgesByIP6(random.choice(bridges)) -def testDistWithFilterIP4(self): -d = bridgedb.Dist.HTTPSDistributor(3, "Foo") -for _ in xrange(250): -d.insert(fakeBridge6(or_addresses=True)) -d.insert(fakeBridge(or_addresses=True)) - -for i in xrange(500): -bridges = d.getBridges(randomIPv4String(), - "faketimestamp", - bridgeFilterRules=[filterBridgesByIP4]) -bridge = random.choice(bridges) -bridge_line = bridge.getConfigLine(addressClass=ipaddr.IPv4Address) -address, portlist = networkstatus.parseALine(bridge_line) -assert type(ipaddr.IPAddress(address)) is ipaddr.IPv4Address -assert filterBridgesByIP4(random.choice(bridges)) - def testDistWithFilterBlockedCountriesAdvanced(self): d = bridgedb.Dist.HTTPSDistributor(3, "Foo") for _ in xrange(250): diff --git a/lib/bridgedb/test/test_Dist.py b/lib/bridgedb/test/test_Dist.py index 9e47a92..82ef823 100644 --- a/lib/bridgedb/test/test_Dist.py +++ b/lib/bridgedb/test/test_Dist.py @@ -288,3 +288,23 @@ class HTTPSDistributorTests(unittest.TestCase): address = address.strip('[]') self.assertIsInstance(ipaddr.IPAddress(address), ipaddr.IPv6Address) self.assertIsNotNone(filterBridgesByIP6(random.choice(bridges))) + +def test_HTTPSDistributor_getBridges_ipv4(self): +"""A request for IPv4 bridges should return IPv4 bridges.""" +dist = Dist.HTTPSDistributor(1, self.key) +[dist.insert(bridge) for bridge in self.bridges[:250]] + +for i in xrange(500): +bridgeRequest = self.randomClientRequest() +bridgeRequest.generateFilters() + +bridges = dist.getBridges(bridgeRequest, "faketimestamp") +self.assertTrue(type(bridges) is list) +self.assertGreater(len(bridges), 0) + +bridge = random.choice(bridges) +bridgeLine = bridge.getBridgeLine(bridgeRequest) +addrport, fingerprint = bridgeLine.split() +address, port = addrport.rsplit(':', 1) +self.assertIsInstance(ipaddr.IPAddress(address), ipaddr.IPv4Address) +self.assertIsNotNone(filterBridgesByIP4(random.choice(bridges))) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Rewrite testDistWithFilterIP6() in legacy_Tests.
commit c1637a017d7e34a79b71829f0918184b63055c6e Author: Isis Lovecruft Date: Tue Apr 21 23:35:33 2015 + Rewrite testDistWithFilterIP6() in legacy_Tests. --- lib/bridgedb/test/legacy_Tests.py | 16 lib/bridgedb/test/test_Dist.py| 22 ++ 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/lib/bridgedb/test/legacy_Tests.py b/lib/bridgedb/test/legacy_Tests.py index 9a0c74f..c495412 100644 --- a/lib/bridgedb/test/legacy_Tests.py +++ b/lib/bridgedb/test/legacy_Tests.py @@ -236,22 +236,6 @@ class IPBridgeDistTests(unittest.TestCase): #self.assertEquals(len(fps), 5) #self.assertTrue(count >= 1) -def testDistWithFilterIP6(self): -d = bridgedb.Dist.HTTPSDistributor(3, "Foo") -for _ in xrange(250): -d.insert(fakeBridge6(or_addresses=True)) -d.insert(fakeBridge(or_addresses=True)) - -for i in xrange(500): -bridges = d.getBridges(randomIPv4String(), - "faketimestamp", - bridgeFilterRules=[filterBridgesByIP6]) -bridge = random.choice(bridges) -bridge_line = bridge.getConfigLine(addressClass=ipaddr.IPv6Address) -address, portlist = networkstatus.parseALine(bridge_line) -assert type(ipaddr.IPAddress(address)) is ipaddr.IPv6Address -assert filterBridgesByIP6(random.choice(bridges)) - def testDistWithFilterBlockedCountriesAdvanced(self): d = bridgedb.Dist.HTTPSDistributor(3, "Foo") for _ in xrange(250): diff --git a/lib/bridgedb/test/test_Dist.py b/lib/bridgedb/test/test_Dist.py index 82ef823..bc437ba 100644 --- a/lib/bridgedb/test/test_Dist.py +++ b/lib/bridgedb/test/test_Dist.py @@ -289,6 +289,28 @@ class HTTPSDistributorTests(unittest.TestCase): self.assertIsInstance(ipaddr.IPAddress(address), ipaddr.IPv6Address) self.assertIsNotNone(filterBridgesByIP6(random.choice(bridges))) +def test_HTTPSDistributor_getBridges_ipv6(self): +"""A request for IPv6 bridges should return IPv6 bridges.""" +dist = Dist.HTTPSDistributor(3, self.key) +[dist.insert(bridge) for bridge in self.bridges[:250]] + +for i in xrange(500): +bridgeRequest = self.randomClientRequest() +bridgeRequest.withIPv6() +bridgeRequest.generateFilters() + +bridges = dist.getBridges(bridgeRequest, "faketimestamp") +self.assertTrue(type(bridges) is list) +self.assertGreater(len(bridges), 0) + +bridge = random.choice(bridges) +bridgeLine = bridge.getBridgeLine(bridgeRequest) +addrport, fingerprint = bridgeLine.split() +address, port = addrport.rsplit(':', 1) +address = address.strip('[]') +self.assertIsInstance(ipaddr.IPAddress(address), ipaddr.IPv6Address) +self.assertIsNotNone(filterBridgesByIP6(random.choice(bridges))) + def test_HTTPSDistributor_getBridges_ipv4(self): """A request for IPv4 bridges should return IPv4 bridges.""" dist = Dist.HTTPSDistributor(1, self.key) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Rewrite testDistWithFilterAll() and testDistWithFilterBoth() in legacy_Tests.
commit 6357566edb74341f84cc3f953ed34bbb1ce01247 Author: Isis Lovecruft Date: Tue Apr 21 23:33:42 2015 + Rewrite testDistWithFilterAll() and testDistWithFilterBoth() in legacy_Tests. --- lib/bridgedb/test/legacy_Tests.py | 35 --- lib/bridgedb/test/test_Dist.py| 48 + 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/lib/bridgedb/test/legacy_Tests.py b/lib/bridgedb/test/legacy_Tests.py index fc4ca5d..043f09b 100644 --- a/lib/bridgedb/test/legacy_Tests.py +++ b/lib/bridgedb/test/legacy_Tests.py @@ -268,41 +268,6 @@ class IPBridgeDistTests(unittest.TestCase): assert type(ipaddr.IPAddress(address)) is ipaddr.IPv4Address assert filterBridgesByIP4(random.choice(bridges)) -def testDistWithFilterBoth(self): -d = bridgedb.Dist.HTTPSDistributor(3, "Foo") -for _ in xrange(250): -d.insert(fakeBridge6(or_addresses=True)) -d.insert(fakeBridge(or_addresses=True)) - -for i in xrange(50): -bridges = d.getBridges(randomIPv4String(), - "faketimestamp", - bridgeFilterRules=[ - filterBridgesByIP4, - filterBridgesByIP6]) -if bridges: -t = bridges.pop() -assert filterBridgesByIP4(t) -assert filterBridgesByIP6(t) -address, portlist = networkstatus.parseALine( -t.getConfigLine(addressClass=ipaddr.IPv4Address)) -assert type(address) is ipaddr.IPv4Address -address, portlist = networkstatus.parseALine( -t.getConfigLine(addressClass=ipaddr.IPv6Address)) -assert type(address) is ipaddr.IPv6Address - - -def testDistWithFilterAll(self): -d = bridgedb.Dist.HTTPSDistributor(3, "Foo") -for _ in xrange(250): -d.insert(fakeBridge6(or_addresses=True)) -d.insert(fakeBridge(or_addresses=True)) - -for i in xrange(5): -b = d.getBridges(randomIPv4String(), "x", bridgeFilterRules=[ -filterBridgesByIP4, filterBridgesByIP6]) -assert len(b) == 0 - def testDistWithFilterBlockedCountriesAdvanced(self): d = bridgedb.Dist.HTTPSDistributor(3, "Foo") for _ in xrange(250): diff --git a/lib/bridgedb/test/test_Dist.py b/lib/bridgedb/test/test_Dist.py index 2d93a19..9e47a92 100644 --- a/lib/bridgedb/test/test_Dist.py +++ b/lib/bridgedb/test/test_Dist.py @@ -24,6 +24,8 @@ from bridgedb.bridges import Bridge from bridgedb.bridges import PluggableTransport from bridgedb.Bridges import BridgeRing from bridgedb.Filters import filterBridgesByNotBlockedIn +from bridgedb.Filters import filterBridgesByIP4 +from bridgedb.Filters import filterBridgesByIP6 from bridgedb.https.request import HTTPSBridgeRequest from bridgedb.proxy import ProxySet from bridgedb.test.util import randomHighPort @@ -240,3 +242,49 @@ class HTTPSDistributorTests(unittest.TestCase): self.assertFalse(b.isBlockedIn('ir')) self.assertNotIn(b.fingerprint, blockedIR) self.assertGreater(len(bridges), 0) + +def test_HTTPSDistributor_getBridges_ipv4_ipv6(self): +"""Asking for bridge addresses which are simultaneously IPv4 and IPv6 +(in that order) should return IPv4 bridges. +""" +dist = Dist.HTTPSDistributor(1, self.key) +[dist.insert(bridge) for bridge in self.bridges[:250]] + +bridgeRequest = self.randomClientRequest() +bridgeRequest.withIPv4() +bridgeRequest.filters.append(filterBridgesByIP6) +bridgeRequest.generateFilters() + +bridges = dist.getBridges(bridgeRequest, 1) +self.assertEqual(len(bridges), 3) + +bridge = random.choice(bridges) +bridgeLine = bridge.getBridgeLine(bridgeRequest) +addrport, fingerprint = bridgeLine.split() +address, port = addrport.rsplit(':', 1) +address = address.strip('[]') +self.assertIsInstance(ipaddr.IPAddress(address), ipaddr.IPv4Address) +self.assertIsNotNone(filterBridgesByIP4(random.choice(bridges))) + +def test_HTTPSDistributor_getBridges_ipv6_ipv4(self): +"""Asking for bridge addresses which are simultaneously IPv6 and IPv4 +(in that order) should return IPv6 bridges. +""" +dist = Dist.HTTPSDistributor(1, self.key) +[dist.insert(bridge) for bridge in self.bridges[:250]] + +bridgeRequest = self.randomClientRequest() +bridgeRequest.withIPv6() +bridgeRequest.generateFilters() +bridgeRequest.filters.append(filterBridgesByIP4) + +bridges = dist.getBridges(bridgeRequest, 1) +self.assertEqual(len(bridges), 3) + +bridge = random.choice(bridges) +bridgeLine = bridge.getB
[tor-commits] [bridgedb/develop] Change PluggableTransport.methodname to be a @property.
commit 70019ff8944cd29de272d34f432247b055045006 Author: Isis Lovecruft Date: Tue Apr 21 03:02:57 2015 + Change PluggableTransport.methodname to be a @property. This ensures that it's always lowercased when set, removing the need for so many lower() calls. --- lib/bridgedb/Filters.py | 12 ++-- lib/bridgedb/bridges.py | 29 ++--- lib/bridgedb/test/test_bridges.py | 10 +- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/lib/bridgedb/Filters.py b/lib/bridgedb/Filters.py index cb5e782..eb7db4e 100644 --- a/lib/bridgedb/Filters.py +++ b/lib/bridgedb/Filters.py @@ -71,19 +71,19 @@ def filterBridgesByTransport(methodname, addressClass=None): if not ((addressClass is IPv4Address) or (addressClass is IPv6Address)): addressClass = IPv4Address +# Ignore case +methodname = methodname.lower() + ruleset = frozenset([methodname, addressClass]) try: return funcs[ruleset] except KeyError: - def _filterByTransport(bridge): for transport in bridge.transports: -if isinstance(transport.address, addressClass): -# ignore method name case -if transport.methodname.lower() == methodname.lower(): -return True +if (transport.methodname == methodname and +isinstance(transport.address, addressClass)): +return True return False - _filterByTransport.__name__ = ("filterBridgesByTransport(%s,%s)" % (methodname, addressClass)) setattr(_filterByTransport, "description", "transport=%s" % methodname) diff --git a/lib/bridgedb/bridges.py b/lib/bridgedb/bridges.py index dc5b78d..c98d54c 100644 --- a/lib/bridgedb/bridges.py +++ b/lib/bridgedb/bridges.py @@ -316,14 +316,13 @@ class PluggableTransport(BridgeAddressBase): super(PluggableTransport, self).__init__() self._port = None self._methodname = None -self._arguments = None +self._blockedIn = {} self.fingerprint = fingerprint self.address = address self.port = port self.methodname = methodname self.arguments = arguments -self._blockedIn = {} # Because we can intitialise this class with the __init__() # parameters, or use the ``updateFromStemTransport()`` method, we'll @@ -464,6 +463,30 @@ class PluggableTransport(BridgeAddressBase): """Reset this ``PluggableTransport``'s port to ``None``.""" self._port = None +@property +def methodname(self): +"""Get this :class:`PluggableTransport`'s methodname. + +:rtype: str +:returns: The (lowercased) methodname of this ``PluggableTransport``, +i.e. ``"obfs3"``, ``"scramblesuit"``, etc. +""" +return self._methodname + +@methodname.setter +def methodname(self, value): +"""Set this ``PluggableTransport``'s methodname. + +.. hint:: The **value** will be automatically lowercased. + +:param str value: The new methodname. +""" +if value: +try: +self._methodname = value.lower() +except (AttributeError, TypeError): +raise TypeError("methodname must be a str or unicode") + def getTransportLine(self, includeFingerprint=True, bridgePrefix=False): """Get a Bridge Line for this :class:`PluggableTransport`. @@ -1317,7 +1340,7 @@ class Bridge(BridgeBackwardsCompatibility): **countryCode**, ``False`` otherwise. """ for pt in self.transports: -if pt.methodname.lower() == methodname.lower(): +if pt.methodname == methodname.lower(): if self.addressIsBlockedIn(countryCode, pt.address, pt.port): logging.info("Transport %s of bridge %s is blocked in %s." % (pt.methodname, self, countryCode)) diff --git a/lib/bridgedb/test/test_bridges.py b/lib/bridgedb/test/test_bridges.py index 499a8c2..db662ae 100644 --- a/lib/bridgedb/test/test_bridges.py +++ b/lib/bridgedb/test/test_bridges.py @@ -659,11 +659,11 @@ class PluggableTransportTests(unittest.TestCase): bridgeLine = pt.getTransportLine() # We have to check for substrings because we don't know which order -# the PT arguments will end up in the bridge line. Fortunately, the -# following three are the only ones which are important to have in -# order: -self.assertTrue(bridgeLine.startswith("voltronPT")) -self.assertSubstring("voltronPT 1.2.3.4:443 " + self.fingerprint, +# the PT arguments will end up in the bridge line. We also have to +# check for the lowercased transport name. Fortunately, the following +# three are the only ones
[tor-commits] [bridgedb/develop] Remove unnecessary use of logSafely() in bridgedb.Bridges.
commit 68434ca69f5a5b38fc877abf03064eddbe879956 Author: Isis Lovecruft Date: Mon Apr 20 03:45:24 2015 + Remove unnecessary use of logSafely() in bridgedb.Bridges. Logging str(bridge) will produce a hashed fingerprint if safelogging is enabled, so there's no use in calling logSafely(bridge.fingerprint). --- lib/bridgedb/Bridges.py | 12 +--- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py index 1a06dd8..4b77cdc 100644 --- a/lib/bridgedb/Bridges.py +++ b/lib/bridgedb/Bridges.py @@ -539,14 +539,12 @@ class FilteredBridgeSplitter(object): """ # The bridge must be running to insert it: if not bridge.flags.running: -logging.warn( -"Skipping hashring insertion for non-running bridge: '%s'" -% logSafely(bridge.fingerprint)) +logging.warn(("Skipping hashring insertion for non-running " + "bridge: %s") % bridge) return index = 0 -logging.debug("Inserting %s into hashring" - % (logSafely(bridge.fingerprint))) +logging.debug("Inserting %s into hashring..." % bridge) for old_bridge in self.bridges[:]: if bridge.fingerprint == old_bridge.fingerprint: self.bridges[index] = bridge @@ -557,8 +555,8 @@ class FilteredBridgeSplitter(object): for ringname, (filterFn, subring) in self.filterRings.items(): if filterFn(bridge): subring.insert(bridge) -logging.debug("Inserted bridge '%s' into '%s' sub hashring" - % (logSafely(bridge.fingerprint), ringname)) +logging.debug("Inserted bridge %s into %s subhashring." % + (bridge, ringname)) def extractFilterNames(self, ringname): """Get the names of the filters applied to a particular sub hashring. ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[bridgedb/develop] Move bridgedb.Dist.HTTPSDistributor → bridgedb.https.distributor.
commit dc91ea443e66223999c5b7a70c4b42025c0ac25c Author: Isis Lovecruft Date: Tue Apr 21 07:32:49 2015 + Move bridgedb.Dist.HTTPSDistributor â bridgedb.https.distributor. * FIXES part of #12506: https://bugs.torproject.org/12506 --- doc/sphinx/source/bridgedb.https.rst|1 + doc/sphinx/source/conf.py |1 + lib/bridgedb/Bridges.py |2 +- lib/bridgedb/Dist.py| 302 --- lib/bridgedb/Main.py| 21 +- lib/bridgedb/https/distributor.py | 328 lib/bridgedb/https/request.py |2 +- lib/bridgedb/https/server.py|2 +- lib/bridgedb/persistent.py |3 +- lib/bridgedb/test/https_helpers.py |4 +- lib/bridgedb/test/legacy_Tests.py | 68 + lib/bridgedb/test/test_Dist.py | 434 --- lib/bridgedb/test/test_https_distributor.py | 405 + lib/bridgedb/test/test_https_server.py |2 +- lib/bridgedb/test/util.py | 33 ++ 15 files changed, 797 insertions(+), 811 deletions(-) diff --git a/doc/sphinx/source/bridgedb.https.rst b/doc/sphinx/source/bridgedb.https.rst index 1512065..36fa6c6 100644 --- a/doc/sphinx/source/bridgedb.https.rst +++ b/doc/sphinx/source/bridgedb.https.rst @@ -7,5 +7,6 @@ bridgedb.https :depth: 3 .. automodule:: bridgedb.https.__init__ +.. automodule:: bridgedb.https.distributor .. automodule:: bridgedb.https.request .. automodule:: bridgedb.https.server diff --git a/doc/sphinx/source/conf.py b/doc/sphinx/source/conf.py index 9b43d0f..5038abb 100644 --- a/doc/sphinx/source/conf.py +++ b/doc/sphinx/source/conf.py @@ -43,6 +43,7 @@ import bridgedb.email.templates import bridgedb.filters import bridgedb.geo import bridgedb.https +import bridgedb.https.distributor import bridgedb.https.request import bridgedb.https.server import bridgedb.Main diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py index 2b56884..7a237fe 100644 --- a/lib/bridgedb/Bridges.py +++ b/lib/bridgedb/Bridges.py @@ -510,7 +510,7 @@ class FilteredBridgeSplitter(object): :ivar bridges: DOCDOC :type distributorName: str :ivar distributorName: The name of this splitter's distributor. See - :meth:`bridgedb.Dist.HTTPSDistributor.setDistributorName`. + :meth:`~bridgedb.https.distributor.HTTPSDistributor.setDistributorName`. """ self.key = key self.filterRings = {} diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 9b9e35c..1be705f 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -12,14 +12,11 @@ """This module has functions to decide which bridges to hand out to whom.""" -import ipaddr import logging -import re import time import bridgedb.Storage -from bridgedb import proxy from bridgedb.Bridges import BridgeRing from bridgedb.Bridges import FilteredBridgeSplitter from bridgedb.crypto import getHMAC @@ -47,305 +44,6 @@ class EmailRequestedKey(Exception): """Raised when an incoming email requested a copy of our GnuPG keys.""" -class HTTPSDistributor(Distributor): -"""A Distributor that hands out bridges based on the IP address of an -incoming request and the current time period. - -:type proxies: :class:`~bridgedb.proxies.ProxySet` -:ivar proxies: All known proxies, which we treat differently. See -:param:`proxies`. -:type hashring: :class:`bridgedb.Bridges.FixedBridgeSplitter` -:ivar hashring: A hashring that assigns bridges to subrings with fixed -proportions. Used to assign bridges into the subrings of this -distributor. -""" - -def __init__(self, totalSubrings, key, proxies=None, answerParameters=None): -"""Create a Distributor that decides which bridges to distribute based -upon the client's IP address and the current time. - -:param int totalSubrings: The number of subhashrings to group clients -into. Note that if ``PROXY_LIST_FILES`` is set in bridgedb.conf, -then the actual number of clusters is one higher than -``totalSubrings``, because the set of all known open proxies is -given its own subhashring. -:param bytes key: The master HMAC key for this distributor. All added -bridges are HMACed with this key in order to place them into the -hashrings. -:type proxies: :class:`~bridgedb.proxy.ProxySet` -:param proxies: A :class:`bridgedb.proxy.ProxySet` containing known -Tor Exit relays and other known proxies. These will constitute -the extra cluster, and any client requesting bridges from one of -these **proxies** will be distributed bridges from a separate -subhashring that is specific to Tor/proxy users. -:type
[tor-commits] [bridgedb/develop] Rewrite commented out testDistWithPortRestrictions() in legacy_Tests.
commit 003165e7875412944b91785431ee1b749fda2a0d Author: Isis Lovecruft Date: Mon Apr 20 03:34:40 2015 + Rewrite commented out testDistWithPortRestrictions() in legacy_Tests. --- lib/bridgedb/test/legacy_Tests.py | 22 -- lib/bridgedb/test/test_Dist.py| 25 + 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/lib/bridgedb/test/legacy_Tests.py b/lib/bridgedb/test/legacy_Tests.py index 85ba722..2f1da67 100644 --- a/lib/bridgedb/test/legacy_Tests.py +++ b/lib/bridgedb/test/legacy_Tests.py @@ -185,28 +185,6 @@ class EmailBridgeDistTests(unittest.TestCase): class IPBridgeDistTests(unittest.TestCase): -#XXX: #6175 breaks this test! -#def testDistWithPortRestrictions(self): -#param = bridgedb.Bridges.BridgeRingParameters(needPorts=[(443, 1)]) -#d = bridgedb.Dist.HTTPSDistributor(3, "Baz", -# answerParameters=param) -#for _ in xrange(32): -#d.insert(fakeBridge(443)) -#for _ in range(256): -#d.insert(fakeBridge()) -#for _ in xrange(32): -#i = randomIP() -#n = d.getBridges(i, "x") -#count = 0 -#fps = {} -#for b in n: -#fps[b.getID()] = 1 -#if b.orport == 443: -#count += 1 -#self.assertEquals(len(fps), len(n)) -#self.assertEquals(len(fps), 5) -#self.assertTrue(count >= 1) - def testDistWithFilterBlockedCountriesAdvanced(self): d = bridgedb.Dist.HTTPSDistributor(3, "Foo") for _ in xrange(250): diff --git a/lib/bridgedb/test/test_Dist.py b/lib/bridgedb/test/test_Dist.py index 18b3e79..e8a17e4 100644 --- a/lib/bridgedb/test/test_Dist.py +++ b/lib/bridgedb/test/test_Dist.py @@ -23,6 +23,7 @@ from bridgedb import Dist from bridgedb.bridges import Bridge from bridgedb.bridges import PluggableTransport from bridgedb.Bridges import BridgeRing +from bridgedb.Bridges import BridgeRingParameters from bridgedb.Filters import filterBridgesByNotBlockedIn from bridgedb.Filters import filterBridgesByIP4 from bridgedb.Filters import filterBridgesByIP6 @@ -282,6 +283,30 @@ class HTTPSDistributorTests(unittest.TestCase): for i in range(4): self.assertItemsEqual(responses[i], responses[i+1]) +def test_HTTPSDistributor_getBridges_with_BridgeRingParameters(self): + param = BridgeRingParameters(needPorts=[(443, 1)]) + dist = Dist.HTTPSDistributor(3, self.key, answerParameters=param) + + bridges = self.bridges[:32] + for b in self.bridges: + b.orPort = 443 + + [dist.insert(bridge) for bridge in bridges] + [dist.insert(bridge) for bridge in self.bridges[:250]] + + for _ in xrange(32): + bridgeRequest = self.randomClientRequest() + answer = dist.getBridges(bridgeRequest, 1) + count = 0 + fingerprints = {} + for bridge in answer: + fingerprints[bridge.identity] = 1 + if bridge.orPort == 443: + count += 1 + self.assertEquals(len(fingerprints), len(answer)) + self.assertGreater(len(fingerprints), 0) + self.assertTrue(count >= 1) + def test_HTTPSDistributor_getBridges_ipv4_ipv6(self): """Asking for bridge addresses which are simultaneously IPv4 and IPv6 (in that order) should return IPv4 bridges. ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Remove the __len__() method from all Distributors.
commit e6357735d612074fe32f2273c52d9254427caa37 Author: Isis Lovecruft Date: Sun Apr 19 03:51:43 2015 + Remove the __len__() method from all Distributors. --- lib/bridgedb/Dist.py |6 -- lib/bridgedb/Main.py |4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index fe81c04..e149d17 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -346,9 +346,6 @@ class HTTPSDistributor(Distributor): return answer -def __len__(self): -return len(self.hashring) - def dumpAssignments(self, f, description=""): self.hashring.dumpAssignments(f, description) @@ -475,9 +472,6 @@ class EmailBasedDistributor(Distributor): return result -def __len__(self): -return len(self.hashring) - def cleanDatabase(self): with bridgedb.Storage.getDB() as db: try: diff --git a/lib/bridgedb/Main.py b/lib/bridgedb/Main.py index f382cc5..ba74b66 100644 --- a/lib/bridgedb/Main.py +++ b/lib/bridgedb/Main.py @@ -215,7 +215,7 @@ def createBridgeRings(cfg, proxyList, key): crypto.getHMAC(key, "HTTPS-IP-Dist-Key"), proxyList, answerParameters=ringParams) -hashring.addRing(ipDistributor, "https", cfg.HTTPS_SHARE) +hashring.addRing(ipDistributor.hashring, "https", cfg.HTTPS_SHARE) # As appropriate, create an email-based distributor. if cfg.EMAIL_DIST and cfg.EMAIL_SHARE: @@ -226,7 +226,7 @@ def createBridgeRings(cfg, proxyList, key): cfg.EMAIL_DOMAIN_RULES.copy(), answerParameters=ringParams, whitelist=cfg.EMAIL_WHITELIST.copy()) -hashring.addRing(emailDistributor, "email", cfg.EMAIL_SHARE) +hashring.addRing(emailDistributor.hashring, "email", cfg.EMAIL_SHARE) # As appropriate, tell the hashring to leave some bridges unallocated. if cfg.RESERVED_SHARE: ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Rewrite testBasicDist() in legacy_Tests.
commit e75d41608d0cec23a4d1240d59f3fb5e2ea593d5 Author: Isis Lovecruft Date: Sun Apr 19 05:31:13 2015 + Rewrite testBasicDist() in legacy_Tests. --- lib/bridgedb/test/legacy_Tests.py |8 lib/bridgedb/test/test_Dist.py| 15 +++ 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/lib/bridgedb/test/legacy_Tests.py b/lib/bridgedb/test/legacy_Tests.py index c495412..fd6a739 100644 --- a/lib/bridgedb/test/legacy_Tests.py +++ b/lib/bridgedb/test/legacy_Tests.py @@ -185,14 +185,6 @@ class EmailBridgeDistTests(unittest.TestCase): class IPBridgeDistTests(unittest.TestCase): -def testBasicDist(self): -d = bridgedb.Dist.HTTPSDistributor(3, "Foo") -for _ in xrange(256): -d.insert(fakeBridge()) -n = d.getBridges("1.2.3.4", "x") -n2 = d.getBridges("1.2.3.4", "x") -self.assertEquals(n, n2) - def testDistWithProxies(self): d = bridgedb.Dist.HTTPSDistributor(3, "Foo", [RhymesWith255ProxySet()]) for _ in xrange(256): diff --git a/lib/bridgedb/test/test_Dist.py b/lib/bridgedb/test/test_Dist.py index bc437ba..23a6492 100644 --- a/lib/bridgedb/test/test_Dist.py +++ b/lib/bridgedb/test/test_Dist.py @@ -243,6 +243,21 @@ class HTTPSDistributorTests(unittest.TestCase): self.assertNotIn(b.fingerprint, blockedIR) self.assertGreater(len(bridges), 0) +def test_HTTPSDistributor_getBridges_same_bridges_to_same_client(self): +"""The same client asking for bridges from the HTTPSDistributor +multiple times in a row should get the same bridges in response each +time. +""" +dist = Dist.HTTPSDistributor(3, self.key) +[dist.insert(bridge) for bridge in self.bridges[:250]] + +bridgeRequest = self.randomClientRequest() +responses = {} +for i in range(5): +responses[i] = dist.getBridges(bridgeRequest, 1) +for i in range(4): +self.assertItemsEqual(responses[i], responses[i+1]) + def test_HTTPSDistributor_getBridges_ipv4_ipv6(self): """Asking for bridge addresses which are simultaneously IPv4 and IPv6 (in that order) should return IPv4 bridges. ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[bridgedb/develop] Move Dist.getNumBridgesPerAnswer() → Distributor.bridgesPerResponse().
commit a51f553e281091bc365d4161da2fb8d1b33923d9 Author: Isis Lovecruft Date: Sat Apr 18 22:41:27 2015 + Move Dist.getNumBridgesPerAnswer() â Distributor.bridgesPerResponse(). It was meant to be a method; it operates on the length of the primary hashring of a Distributor. Having it outside of the class that it interacts with is just wacky. * CHANGE getNumBridgesPerAnswer into a method for the Distributor class. * CHANGE the unittests for the function to take this into account. --- lib/bridgedb/Dist.py | 43 +- lib/bridgedb/test/test_Dist.py | 56 ++-- 2 files changed, 50 insertions(+), 49 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index e66c1e6..93c08c1 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -48,26 +48,13 @@ class EmailRequestedKey(Exception): """Raised when an incoming email requested a copy of our GnuPG keys.""" -def getNumBridgesPerAnswer(ring, max_bridges_per_answer=3): -if len(ring) < 20: -n_bridges_per_answer = 1 -if 20 <= len(ring) < 100: -n_bridges_per_answer = min(2, max_bridges_per_answer) -if len(ring) >= 100: -n_bridges_per_answer = max_bridges_per_answer - -logging.debug("Returning %d bridges from ring of len: %d" % - (n_bridges_per_answer, len(ring))) - -return n_bridges_per_answer - - class Distributor(object): """Distributes bridges to clients.""" def __init__(self): super(Distributor, self).__init__() self.name = None +self.hashring = None def setDistributorName(self, name): """Set a **name** for identifying this distributor. @@ -89,6 +76,21 @@ class Distributor(object): self.name = name self.hashring.distributorName = name +def bridgesPerResponse(self, hashring=None, maximum=3): +if hashring is None: +hashring = self.hashring + +if len(hashring) < 20: +n = 1 +if 20 <= len(hashring) < 100: +n = min(2, maximum) +if len(hashring) >= 100: +n = maximum + +logging.debug("Returning %d bridges from ring of len: %d" % + (n, len(hashring))) +return n + class HTTPSDistributor(Distributor): """A Distributor that hands out bridges based on the IP address of an @@ -157,6 +159,9 @@ class HTTPSDistributor(Distributor): self.setDistributorName('HTTPS') +def bridgesPerResponse(self, hashring=None, maximum=3): +return super(HTTPSDistributor, self).bridgesPerResponse(hashring, maximum) + @classmethod def getSubnet(cls, ip, usingProxy=False, proxySubnets=4): """Map all clients whose **ip**s are within the same subnet to the same @@ -386,7 +391,7 @@ class HTTPSDistributor(Distributor): populate_from=self.hashring.bridges) # Determine the appropriate number of bridges to give to the client: -returnNum = getNumBridgesPerAnswer(ring, max_bridges_per_answer=N) +returnNum = self.bridgesPerResponse(ring, maximum=N) answer = ring.getBridges(position, returnNum) return answer @@ -440,6 +445,9 @@ class EmailBasedDistributor(Distributor): self.setDistributorName('Email') +def bridgesPerResponse(self, hashring=None, maximum=3): +return super(EmailBasedDistributor, self).bridgesPerResponse(hashring, maximum) + def insert(self, bridge): """Assign a bridge to this distributor.""" self.hashring.insert(bridge) @@ -515,9 +523,8 @@ class EmailBasedDistributor(Distributor): filterBridgesByRules(ruleset), populate_from=self.hashring.bridges) -numBridgesToReturn = getNumBridgesPerAnswer(ring, - max_bridges_per_answer=N) -result = ring.getBridges(pos, numBridgesToReturn) +returnNum = self.bridgesPerResponse(ring, maximum=N) +result = ring.getBridges(pos, returnNum) db.setEmailTime(bridgeRequest.client, now) db.commit() diff --git a/lib/bridgedb/test/test_Dist.py b/lib/bridgedb/test/test_Dist.py index a3c8308..f47449c 100644 --- a/lib/bridgedb/test/test_Dist.py +++ b/lib/bridgedb/test/test_Dist.py @@ -63,37 +63,6 @@ def _generateFakeBridges(n=500): BRIDGES = _generateFakeBridges() -class GetNumBridgesPerAnswerTests(unittest.TestCase): -"""Unittests for :func:`bridgedb.Dist.getNumBridgesPerAnswer`.""" - -def setUp(self): -self.key = 'aQpeOFIj8q20s98awfoiq23rpOIjFaqpEWFoij1X' -self.ring = BridgeRing(self.key) -self.bridges = _generateFakeBridges() - -def test_Dist_getNumBridgesPerAnswer_120(self): -[self.ring.insert(bridge) for bridge in self.bridges[:120]
[tor-commits] [bridgedb/develop] Teach Bridge._getTransportForRequest() to filter blocked addresses.
commit b77e0126da7132c02453111310231d4912818a66 Author: Isis Lovecruft Date: Sat Apr 18 06:25:49 2015 + Teach Bridge._getTransportForRequest() to filter blocked addresses. --- lib/bridgedb/bridges.py | 52 +-- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/lib/bridgedb/bridges.py b/lib/bridgedb/bridges.py index 8f4f853..dc5b78d 100644 --- a/lib/bridgedb/bridges.py +++ b/lib/bridgedb/bridges.py @@ -1040,6 +1040,13 @@ class Bridge(BridgeBackwardsCompatibility): :term:`Bridge Line` based upon the client identifier in the **bridgeRequest**. +.. warning:: If this bridge doesn't have any of the requested +pluggable transport type (optionally, not blocked in whichever +countries the user doesn't want their bridges to be blocked in), +then this method returns ``None``. This should only happen +rarely, because the bridges are filtered into the client's +hashring based on the **bridgeRequest** options. + :type bridgeRequest: :class:`bridgedb.bridgerequest.BridgeRequestBase` :param bridgeRequest: A ``BridgeRequest`` which stores all of the client-specified options for which type of bridge they want to @@ -1056,29 +1063,40 @@ class Bridge(BridgeBackwardsCompatibility): return a :term:`Bridge Line` for the requested pluggable transport type. """ +desired = bridgeRequest.justOnePTType() addressClass = bridgeRequest.addressClass -desiredTransport = bridgeRequest.justOnePTType() -hashringPosition = bridgeRequest.getHashringPlacement(bridgeRequest.client, - 'Order-Or-Addresses') logging.info("Bridge %s answering request for %s transport..." % - (safelog.logSafely(self.fingerprint), desiredTransport)) + (self, desired)) + # Filter all this Bridge's ``transports`` according to whether or not -# their ``methodname`` matches the requested transport, i.e. only -# 'obfs3' transports, or only 'scramblesuit' transports: -transports = filter(lambda pt: desiredTransport == pt.methodname, -self.transports) +# their ``methodname`` matches the requested transport: +transports = filter(lambda pt: pt.methodname == desired, self.transports) # Filter again for whichever of IPv4 or IPv6 was requested: transports = filter(lambda pt: isinstance(pt.address, addressClass), transports) -if transports: -return transports[hashringPosition % len(transports)] -else: +if not transports: raise PluggableTransportUnavailable( -("Client requested transport %s from bridge %s, but this " - "bridge doesn't have any of that transport!") % -(desiredTransport, self.fingerprint)) +("Client requested transport %s, but bridge %s doesn't " +"have any of that transport!") % (desired, self)) + + +unblocked = [] +for pt in transports: +if not sum([self.transportIsBlockedIn(cc, pt.methodname) +for cc in bridgeRequest.notBlockedIn]): +unblocked.append(pt) + +if unblocked: +position = bridgeRequest.getHashringPlacement('Order-Or-Addresses') +return transports[position % len(unblocked)] +else: +logging.warn(("Client requested transport %s%s, but bridge %s " + "doesn't have any of that transport!") % + (desired, " not blocked in %s" % + " ".join(bridgeRequest.notBlockedIn) + if bridgeRequest.notBlockedIn else "", self)) def _getVanillaForRequest(self, bridgeRequest): """If vanilla bridges were requested, return the assigned @@ -1235,9 +1253,13 @@ class Bridge(BridgeBackwardsCompatibility): logging.info("Bridge request was not valid. Dropping request.") return # XXX raise error perhaps? +bridgeLine = None + if bridgeRequest.transports: pt = self._getTransportForRequest(bridgeRequest) -bridgeLine = pt.getTransportLine(includeFingerprint, bridgePrefix) +if pt: +bridgeLine = pt.getTransportLine(includeFingerprint, + bridgePrefix) else: addrport = self._getVanillaForRequest(bridgeRequest) bridgeLine = self._constructBridgeLine(addrport, ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Add another test for Bridge.getBridgeLine() when the bridge is blocked.
commit 1d44a42fdec2763ab868c091756a1446eb839737 Author: Isis Lovecruft Date: Sat Apr 18 03:27:28 2015 + Add another test for Bridge.getBridgeLine() when the bridge is blocked. --- lib/bridgedb/test/test_bridges.py | 18 ++ 1 file changed, 18 insertions(+) diff --git a/lib/bridgedb/test/test_bridges.py b/lib/bridgedb/test/test_bridges.py index e48e20a..d7dd810 100644 --- a/lib/bridgedb/test/test_bridges.py +++ b/lib/bridgedb/test/test_bridges.py @@ -1466,6 +1466,24 @@ class BridgeTests(unittest.TestCase): self.assertIn('179.178.155.140:36489', line) self.assertIn('2C3225C4805331025E211F4B6E5BF45C333FDD2C', line) +def test_Bridge_getBridgeLine_blocked_and_request_without_block(self): +"""Calling getBridgeLine() with a valid request for bridges not blocked in +Iran, when the bridge is completely blocked in Iran, shouldn't return +a bridge line. +""" +self.bridge.updateFromNetworkStatus(self.networkstatus) +self.bridge.updateFromServerDescriptor(self.serverdescriptor) +self.bridge.updateFromExtraInfoDescriptor(self.extrainfo) + +self.bridge.setBlockedIn('ir') + +request = BridgeRequestBase() +request.isValid(True) +request.withoutBlockInCountry('IR') +line = self.bridge.getBridgeLine(request) + +self.assertIsNone(line) + def test_Bridge_getBridgeLine_IPv6(self): """Calling getBridgeLine() with a valid request for IPv6 bridges should return a bridge line. ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Fix Filters.filterBridgesByNotBlockedIn to work with new Bridge class.
commit 98cf68d778480aa005e5914cac47164f169b87b9 Author: Isis Lovecruft Date: Thu Apr 16 20:37:24 2015 + Fix Filters.filterBridgesByNotBlockedIn to work with new Bridge class. --- lib/bridgedb/Filters.py | 37 + lib/bridgedb/bridgerequest.py |4 +--- lib/bridgedb/test/legacy_Tests.py |2 +- 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/lib/bridgedb/Filters.py b/lib/bridgedb/Filters.py index 94d4325..41df297 100644 --- a/lib/bridgedb/Filters.py +++ b/lib/bridgedb/Filters.py @@ -92,28 +92,25 @@ def filterBridgesByTransport(methodname, addressClass=None): funcs[ruleset] = _filterByTransport return _filterByTransport -def filterBridgesByNotBlockedIn(countryCode, addressClass=None, methodname=None): -""" if at least one address:port of the selected addressClass and -(optional) transport type is not blocked in countryCode, return True +def filterBridgesByNotBlockedIn(countryCode): +"""Return ``True`` if at least one of a bridge's (transport) bridgelines isn't +known to be blocked in **countryCode**. + +:param str countryCode: A two-letter country code. +:rtype: bool +:returns: ``True`` if at least one address of the bridge isn't blocked. +``False`` otherwise. """ -# default to IPv4 if not specified -if addressClass is None: addressClass = IPv4Address -assert (addressClass) in (IPv4Address, IPv6Address) -ruleset = frozenset([countryCode, addressClass, methodname]) +countryCode = countryCode.lower() +ruleset = frozenset([countryCode]) try: return funcs[ruleset] except KeyError: -def f(bridge): -if bridge.isBlocked(countryCode, addressClass, methodname): -if addressClass is IPv4Address: ac = "IPv4" -else: ac = "IPv6" -logmsg = "Removing %s from set of results for country" -logmsg += " '%s' with address class %s and transport %s" -logging.debug(logmsg % ( bridge.fingerprint, countryCode, ac, -methodname)) +def _filterByNotBlockedIn(bridge): +if bridge.isBlockedIn(countryCode): return False -return True # not blocked -f.__name__ = "filterBridgesNotBlockedIn(%s,%s,%s)" % \ -(countryCode,methodname,addressClass) -funcs[ruleset] = f -return f +return True +_filterByNotBlockedIn.__name__ = "filterBridgesByNotBlockedIn(%s)" % countryCode +setattr(_filterByNotBlockedIn, "description", "unblocked=%s" % countryCode) +funcs[ruleset] = _filterByNotBlockedIn +return _filterByNotBlockedIn diff --git a/lib/bridgedb/bridgerequest.py b/lib/bridgedb/bridgerequest.py index f4eaaa4..532558d 100644 --- a/lib/bridgedb/bridgerequest.py +++ b/lib/bridgedb/bridgerequest.py @@ -182,6 +182,4 @@ class BridgeRequestBase(object): self.addFilter(Filters.filterBridgesByTransport(transport, self.addressClass)) for country in self.notBlockedIn: -self.addFilter(Filters.filterBridgesByNotBlockedIn(country.lower(), - self.addressClass, - transport)) + self.addFilter(Filters.filterBridgesByNotBlockedIn(country.lower())) diff --git a/lib/bridgedb/test/legacy_Tests.py b/lib/bridgedb/test/legacy_Tests.py index cc1ba6d..5621515 100644 --- a/lib/bridgedb/test/legacy_Tests.py +++ b/lib/bridgedb/test/legacy_Tests.py @@ -357,7 +357,7 @@ class IPBridgeDistTests(unittest.TestCase): for i in xrange(5): b = d.getBridges(randomIPString(), "x", 1, bridgeFilterRules=[ -filterBridgesByNotBlockedIn("cn", methodname='obfs2'), +filterBridgesByNotBlockedIn("cn"), filterBridgesByTransport('obfs2'), ]) try: assert len(b) > 0 ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Add Bridge.identity property and replace all usage of getID().
commit 5fec5eb3e5f8901a08a741ab57cf48b9126e41ee Author: Isis Lovecruft Date: Sat Apr 18 00:48:26 2015 + Add Bridge.identity property and replace all usage of getID(). --- lib/bridgedb/Bridges.py | 25 ++--- lib/bridgedb/Filters.py |2 +- lib/bridgedb/bridges.py | 33 +++-- 3 files changed, 42 insertions(+), 18 deletions(-) diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py index b8fdd2e..5742794 100644 --- a/lib/bridgedb/Bridges.py +++ b/lib/bridgedb/Bridges.py @@ -25,8 +25,6 @@ import bridgedb.Bucket from bridgedb.bridges import Bridge from bridgedb.crypto import getHMACFunc from bridgedb.parse import addr -from bridgedb.parse.fingerprint import toHex -from bridgedb.parse.fingerprint import fromHex from bridgedb.parse.fingerprint import isValidFingerprint from bridgedb.safelog import logSafely @@ -221,13 +219,12 @@ class BridgeRing(BridgeHolder): if val == 'stable' and bridge.flags.stable: subring.insert(bridge) -ident = bridge.getID() -pos = self.hmac(ident) -if not self.bridges.has_key(pos): +pos = self.hmac(bridge.identity) +if not pos in self.bridges: self.sortedKeys.append(pos) self.isSorted = False self.bridges[pos] = bridge -self.bridgesByID[ident] = bridge +self.bridgesByID[bridge.identity] = bridge logging.debug("Adding %s to %s" % (bridge.address, self.name)) def _sort(self): @@ -330,11 +327,11 @@ class BridgeRing(BridgeHolder): logging.info("Dumping bridge assignments for %s..." % self.name) for b in self.bridges.itervalues(): desc = [ description ] -ident = b.getID() for tp,val,_,subring in self.subrings: -if subring.getBridgeByID(ident): +if subring.getBridgeByID(b.identity): desc.append("%s=%s"%(tp,val)) -f.write("%s %s\n"%( toHex(ident), " ".join(desc).strip())) +f.write("%s %s\n" % (b.fingerprint, " ".join(desc).strip())) + class FixedBridgeSplitter(BridgeHolder): """A bridgeholder that splits bridges up based on an hmac and assigns @@ -348,7 +345,7 @@ class FixedBridgeSplitter(BridgeHolder): def insert(self, bridge): # Grab the first 4 bytes -digest = self.hmac(bridge.getID()) +digest = self.hmac(bridge.identity) pos = long( digest[:8], 16 ) which = pos % len(self.rings) self.rings[which].insert(bridge) @@ -467,11 +464,9 @@ class BridgeSplitter(BridgeHolder): if not bridge.flags.running: return -bridgeID = bridge.fingerprint - # Determine which ring to put this bridge in if we haven't seen it # before. -pos = self.hmac(bridgeID) +pos = self.hmac(bridge.identity) n = int(pos[:8], 16) % self.totalP pos = bisect.bisect_right(self.pValues, n) - 1 assert 0 <= pos < len(self.rings) @@ -668,7 +663,7 @@ class FilteredBridgeSplitter(BridgeHolder): if g(b): # ghetto. get subring flags, ports for tp,val,_,subring in r.subrings: -if subring.getBridgeByID(b.getID()): +if subring.getBridgeByID(b.identity): desc.append("%s=%s"%(tp,val)) try: desc.extend(g.description.split()) @@ -693,4 +688,4 @@ class FilteredBridgeSplitter(BridgeHolder): # add to assignments desc = "%s %s" % (description.strip(), " ".join([v for k,v in grouped.items()]).strip()) -f.write("%s %s\n"%( toHex(b.getID()), desc)) +f.write("%s %s\n" % (b.fingerprint, desc)) diff --git a/lib/bridgedb/Filters.py b/lib/bridgedb/Filters.py index 41df297..fb0197b 100644 --- a/lib/bridgedb/Filters.py +++ b/lib/bridgedb/Filters.py @@ -17,7 +17,7 @@ def filterAssignBridgesToRing(hmac, numRings, assignedRing): return funcs[ruleset] except KeyError: def _assignBridgesToRing(bridge): -digest = hmac(bridge.getID()) +digest = hmac(bridge.identity) pos = long( digest[:8], 16 ) which = pos % numRings + 1 diff --git a/lib/bridgedb/bridges.py b/lib/bridgedb/bridges.py index 541e735..c8c7a30 100644 --- a/lib/bridgedb/bridges.py +++ b/lib/bridgedb/bridges.py @@ -178,6 +178,36 @@ class BridgeAddressBase(object): self._fingerprint = None @property +def identity(self): +"""Get this Bridge's identity digest. + +:rtype: bytes +:returns: The binary-encoded SHA-1 hash digest of the public half of +this Bridge's identity key, if available; otherwise, returns +``None``. +""" +if self.fingerprint: +return fromHex(self.fingerprint) + +
[tor-commits] [bridgedb/develop] Add tests for https.request.HTTPSBridgeRequest and BridgeRequestBase.
commit 8cd195e2a518694094f53bb24921eb499e31c270 Author: Isis Lovecruft Date: Tue Apr 14 10:15:23 2015 + Add tests for https.request.HTTPSBridgeRequest and BridgeRequestBase. --- lib/bridgedb/test/test_bridgerequest.py | 18 +++- lib/bridgedb/test/test_https_request.py | 75 +++ 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/lib/bridgedb/test/test_bridgerequest.py b/lib/bridgedb/test/test_bridgerequest.py index b4da71b..3392a4e 100644 --- a/lib/bridgedb/test/test_bridgerequest.py +++ b/lib/bridgedb/test/test_bridgerequest.py @@ -40,5 +40,19 @@ class BridgeRequestBaseTests(unittest.TestCase): """BridgeRequestBase.withPluggableTransportType() should add the pluggable transport type to the ``transport`` attribute. """ -self.request.withPluggableTransportType('huggable-transport') -self.assertIn('huggable-transport', self.request.transports) +self.request.withPluggableTransportType('huggable_transport') +self.assertIn('huggable_transport', self.request.transports) + +def test_BridgeRequestBase_getHashringPlacement_without_client(self): +"""BridgeRequestBase.getHashringPlacement() without a client parameter +should use the default client identifier string. +""" +self.assertEqual(self.request.getHashringPlacement(''), + 3486762050L) + +def test_BridgeRequestBase_getHashringPlacement_with_client(self): +"""BridgeRequestBase.getHashringPlacement() with a client parameter +should use the client identifier string. +""" +self.assertEqual(self.request.getHashringPlacement('', client='you'), + 2870307088L) diff --git a/lib/bridgedb/test/test_https_request.py b/lib/bridgedb/test/test_https_request.py new file mode 100644 index 000..f4f6640 --- /dev/null +++ b/lib/bridgedb/test/test_https_request.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- +#_ +# +# This file is part of BridgeDB, a Tor bridge distribution system. +# +# :authors: Isis Lovecruft 0xA3ADB67A2CDB8B35 +# please also see AUTHORS file +# :copyright: (c) 2007-2015, The Tor Project, Inc. +# (c) 2014-2015, Isis Lovecruft +# :license: see LICENSE for licensing information +#_ + + +from twisted.trial import unittest + +from bridgedb.bridgerequest import IRequestBridges +from bridgedb.https import request + + +class MockRequest(object): +def __init__(self, args): +self.args = args + + +class HTTPSBridgeRequestTests(unittest.TestCase): +"""Unittests for :class:`bridgedb.https.request.HTTPSBridgeRequest`.""" + +def setUp(self): +"""Setup test run.""" +self.request = request.HTTPSBridgeRequest() + +def test_HTTPSBridgeRequest_implements_IRequestBridges(self): +"""HTTPSBridgeRequest should implement IRequestBridges interface.""" + self.assertTrue(IRequestBridges.implementedBy(request.HTTPSBridgeRequest)) + +def test_HTTPSBridgeRequest_withIPversion(self): +"""HTTPSBridgeRequest.withIPversion({ipv6=[â¦]}) should store that the +client wanted IPv6 bridges.""" +parameters = {'ipv6': 'wo'} +self.request.withIPversion(parameters) + +def test_HTTPSBridgeRequest_withoutBlockInCountry_IR(self): +"""HTTPSBridgeRequest.withoutBlockInCountry() should add the country CC +to the ``notBlockedIn`` attribute. +""" +httprequest = MockRequest({'unblocked': ['IR']}) +self.request.withoutBlockInCountry(httprequest) +self.assertIn('IR', self.request.notBlockedIn) + +def test_HTTPSBridgeRequest_withoutBlockInCountry_US(self): +"""HTTPSBridgeRequest.withoutBlockInCountry() should add the country CC +to the ``notBlockedIn`` attribute (and not any other countries). +""" +httprequest = MockRequest({'unblocked': ['US']}) +self.request.withoutBlockInCountry(httprequest) +self.assertNotIn('IR', self.request.notBlockedIn) + +def test_HTTPSBridgeRequest_withoutBlockInCountry_no_addClientCountryCode(self): +"""HTTPSBridgeRequest.withoutBlockInCountry(), when +addClientCountryCode=False, shouldn't add the client's country code to the +``notBlockedIn`` attribute. +""" +httprequest = MockRequest({'unblocked': ['NL']}) +self.request = request.HTTPSBridgeRequest(addClientCountryCode=False) +self.request.client = '5.5.5.5' +self.request.withoutBlockInCountry(httprequest) +self.assertItemsEqual(['NL'], self.request.notBlockedIn) + +def test_HTTPSBridgeRequest_withPluggableTransportType(self): +"""HTTPSBridgeRequest.withPluggableTransportType() should add the +pluggable transport type t
[tor-commits] [bridgedb/develop] BridgeRequest.notBlockedIn country codes should be lowercased.
commit c712736cc04b0423a18fb9582e8d11c0bf663057 Author: Isis Lovecruft Date: Thu Apr 16 07:02:44 2015 + BridgeRequest.notBlockedIn country codes should be lowercased. --- lib/bridgedb/bridgerequest.py |4 ++-- lib/bridgedb/https/request.py |4 ++-- lib/bridgedb/test/test_bridgerequest.py |2 +- lib/bridgedb/test/test_https_request.py | 12 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/bridgedb/bridgerequest.py b/lib/bridgedb/bridgerequest.py index f7aa031..f4eaaa4 100644 --- a/lib/bridgedb/bridgerequest.py +++ b/lib/bridgedb/bridgerequest.py @@ -150,7 +150,7 @@ class BridgeRequestBase(object): self.addressClass = ipaddr.IPv6Address def withoutBlockInCountry(self, country): -self.notBlockedIn.append(country) +self.notBlockedIn.append(country.lower()) def withPluggableTransportType(self, pt): self.transports.append(pt) @@ -182,6 +182,6 @@ class BridgeRequestBase(object): self.addFilter(Filters.filterBridgesByTransport(transport, self.addressClass)) for country in self.notBlockedIn: -self.addFilter(Filters.filterBridgesByNotBlockedIn(country, +self.addFilter(Filters.filterBridgesByNotBlockedIn(country.lower(), self.addressClass, transport)) diff --git a/lib/bridgedb/https/request.py b/lib/bridgedb/https/request.py index 37b3ed6..0ae52c7 100644 --- a/lib/bridgedb/https/request.py +++ b/lib/bridgedb/https/request.py @@ -106,7 +106,7 @@ class HTTPSBridgeRequest(bridgerequest.BridgeRequestBase): pass else: if country: -self.notBlockedIn.append(country) +self.notBlockedIn.append(country.lower()) logging.info("HTTPS request for bridges not blocked in: %r" % country) @@ -116,7 +116,7 @@ class HTTPSBridgeRequest(bridgerequest.BridgeRequestBase): if addr.isIPAddress(self.client): country = geo.getCountryCode(ipaddr.IPAddress(self.client)) if country: -self.notBlockedIn.append(country) +self.notBlockedIn.append(country.lower()) logging.info( ("HTTPS client's bridges also shouldn't be blocked " "in their GeoIP country code: %s") % country) diff --git a/lib/bridgedb/test/test_bridgerequest.py b/lib/bridgedb/test/test_bridgerequest.py index 3392a4e..ccbf406 100644 --- a/lib/bridgedb/test/test_bridgerequest.py +++ b/lib/bridgedb/test/test_bridgerequest.py @@ -34,7 +34,7 @@ class BridgeRequestBaseTests(unittest.TestCase): to the ``notBlockedIn`` attribute. """ self.request.withoutBlockInCountry('US') -self.assertIn('US', self.request.notBlockedIn) +self.assertIn('us', self.request.notBlockedIn) def test_BridgeRequestBase_withPluggableTransportType(self): """BridgeRequestBase.withPluggableTransportType() should add the diff --git a/lib/bridgedb/test/test_https_request.py b/lib/bridgedb/test/test_https_request.py index 286e6eb..c39662f 100644 --- a/lib/bridgedb/test/test_https_request.py +++ b/lib/bridgedb/test/test_https_request.py @@ -43,28 +43,28 @@ class HTTPSBridgeRequestTests(unittest.TestCase): """HTTPSBridgeRequest.withoutBlockInCountry() should add the country CC to the ``notBlockedIn`` attribute. """ -httprequest = MockRequest({'unblocked': ['IR']}) +httprequest = MockRequest({'unblocked': ['ir']}) self.request.withoutBlockInCountry(httprequest) -self.assertIn('IR', self.request.notBlockedIn) +self.assertIn('ir', self.request.notBlockedIn) def test_HTTPSBridgeRequest_withoutBlockInCountry_US(self): """HTTPSBridgeRequest.withoutBlockInCountry() should add the country CC to the ``notBlockedIn`` attribute (and not any other countries). """ -httprequest = MockRequest({'unblocked': ['US']}) +httprequest = MockRequest({'unblocked': ['us']}) self.request.withoutBlockInCountry(httprequest) -self.assertNotIn('IR', self.request.notBlockedIn) +self.assertNotIn('ir', self.request.notBlockedIn) def test_HTTPSBridgeRequest_withoutBlockInCountry_no_addClientCountryCode(self): """HTTPSBridgeRequest.withoutBlockInCountry(), when addClientCountryCode=False, shouldn't add the client's country code to the ``notBlockedIn`` attribute. """ -httprequest = MockRequest({'unblocked': ['NL']}) +httprequest = MockRequest({'unblocked': ['nl']}) self.request = request.HTTPSBridgeRequest(addClientCountryCode=False)
[tor-commits] [bridgedb/develop] Add two more tests for Bridge.getBridgeLine() for blocked PTs.
commit 534969dff39cd0307838bda213f0b183f6c5b24f Author: Isis Lovecruft Date: Sat Apr 18 05:12:12 2015 + Add two more tests for Bridge.getBridgeLine() for blocked PTs. --- lib/bridgedb/test/test_bridges.py | 41 + 1 file changed, 41 insertions(+) diff --git a/lib/bridgedb/test/test_bridges.py b/lib/bridgedb/test/test_bridges.py index d7dd810..499a8c2 100644 --- a/lib/bridgedb/test/test_bridges.py +++ b/lib/bridgedb/test/test_bridges.py @@ -1484,6 +1484,47 @@ class BridgeTests(unittest.TestCase): self.assertIsNone(line) +def test_Bridge_getBridgeLine_blocked_pt_and_request_without_block_pt(self): +"""Calling getBridgeLine() with a valid request for obfs3 bridges not +blocked in Iran, when the obfs3 line is blocked in Iran, shouldn't +return a bridge line. +""" +self.bridge.updateFromNetworkStatus(self.networkstatus) +self.bridge.updateFromServerDescriptor(self.serverdescriptor) +self.bridge.updateFromExtraInfoDescriptor(self.extrainfo) + +self.bridge.setBlockedIn('ir', methodname="obfs3") + +request = BridgeRequestBase() +request.isValid(True) +request.withoutBlockInCountry('IR') +request.withPluggableTransportType('obfs3') +line = self.bridge.getBridgeLine(request) + +self.assertIsNone(line) + +def test_Bridge_getBridgeLine_blocked_obfs3_and_request_without_block_obfs4(self): +"""Calling getBridgeLine() with a valid request for obfs4 bridges not +blocked in Iran, when the obfs3 line is blocked in Iran, should return +a bridge line. +""" +self.bridge.updateFromNetworkStatus(self.networkstatus) +self.bridge.updateFromServerDescriptor(self.serverdescriptor) +self.bridge.updateFromExtraInfoDescriptor(self.extrainfo) + +self.bridge.setBlockedIn('ir', methodname="obfs3") + +request = BridgeRequestBase() +request.isValid(True) +request.withoutBlockInCountry('IR') +request.withPluggableTransportType('obfs4') +line = self.bridge.getBridgeLine(request) + +self.assertIsNotNone(line) +self.assertIn('obfs4', line) +self.assertIn('179.178.155.140:36493', line) +self.assertIn('2C3225C4805331025E211F4B6E5BF45C333FDD2C', line) + def test_Bridge_getBridgeLine_IPv6(self): """Calling getBridgeLine() with a valid request for IPv6 bridges should return a bridge line. ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Add additional test utilities for generating random valid IPs.
commit 372206bb8a73f5229b606a60f40de1c71e4804fe Author: Isis Lovecruft Date: Sat Apr 18 03:15:19 2015 + Add additional test utilities for generating random valid IPs. --- lib/bridgedb/test/util.py | 25 + 1 file changed, 25 insertions(+) diff --git a/lib/bridgedb/test/util.py b/lib/bridgedb/test/util.py index 4aa2709..2d0c020 100644 --- a/lib/bridgedb/test/util.py +++ b/lib/bridgedb/test/util.py @@ -25,6 +25,7 @@ from functools import wraps from twisted.trial import unittest from bridgedb import util as bdbutil +from bridgedb.parse.addr import isIPAddress def fileCheckDecorator(func): @@ -121,6 +122,9 @@ def bracketIPv6(ip): def randomPort(): return random.randint(1, 65535) +def randomHighPort(): +return random.randint(1024, 65535) + def randomIPv4(): return ipaddr.IPv4Address(random.getrandbits(32)) @@ -143,6 +147,27 @@ def randomIPString(): return randomIPv4String() return randomIPv6String() +def valid(func): +"""Wrapper for the above ``randomIPv*`` functions to ensure they only +return addresses which BridgeDB considers "valid". + +.. seealso:: :func:`bridgedb.parse.addr.isIPAddress` +""" +@wraps(func) +def wrapper(): +ip = None +while not isIPAddress(ip): +ip = func() +return ip +return wrapper + +randomValidIPv4 = valid(randomIPv4) +randomValidIPv6 = valid(randomIPv6) +randomValidIP = valid(randomIP) +randomValidIPv4String = valid(randomIPv4String) +randomValidIPv6String = valid(randomIPv6String) +randomValidIPString = valid(randomIPString) + #: Mixin class for use with :api:`~twisted.trial.unittest.TestCase`. A #: ``TestCaseMixin`` can be used to add additional methods, which should be ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Separate DummyBridge._randomORPort() into its own test utility.
commit 0214b0e9ddceca512bd8b7a9c3b052572c4511e4 Author: Isis Lovecruft Date: Sat Apr 18 00:50:36 2015 + Separate DummyBridge._randomORPort() into its own test utility. --- lib/bridgedb/test/util.py | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/bridgedb/test/util.py b/lib/bridgedb/test/util.py index fe662da..4aa2709 100644 --- a/lib/bridgedb/test/util.py +++ b/lib/bridgedb/test/util.py @@ -118,6 +118,9 @@ def bracketIPv6(ip): """Put brackets around an IPv6 address, just as tor does.""" return "[%s]" % ip +def randomPort(): +return random.randint(1, 65535) + def randomIPv4(): return ipaddr.IPv4Address(random.getrandbits(32)) @@ -185,8 +188,6 @@ class DummyBridge(object): ptArgs = {} -def _randORPort(self): return random.randint(9001, ) - def __init__(self): """Create a mocked bridge suitable for testing distributors and web resource rendering. @@ -194,12 +195,10 @@ class DummyBridge(object): ipv4 = randomIPv4() self.nickname = "bridge-{0}".format(ipv4) self.address = ipaddr.IPv4Address(ipv4) -self.orPort = self._randORPort() +self.orPort = randomPort() self.fingerprint = "".join(random.choice('abcdef0123456789') for _ in xrange(40)) -self.orAddresses = [ -(randomIPv6(), self._randORPort(), 6) -] +self.orAddresses = [(randomIPv6(), randomPort(), 6)] def getBridgeLine(self, bridgeRequest, includeFingerprint=True): """Get a "torrc" bridge config line to give to a client.""" ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Add tests for bridgedb.Dist module.
commit 6c10de805e607e9c27c1f3ba4d79097c11c76dbb Author: Isis Lovecruft Date: Sat Apr 18 03:16:31 2015 + Add tests for bridgedb.Dist module. --- lib/bridgedb/test/test_Dist.py | 245 1 file changed, 245 insertions(+) diff --git a/lib/bridgedb/test/test_Dist.py b/lib/bridgedb/test/test_Dist.py new file mode 100644 index 000..a3c8308 --- /dev/null +++ b/lib/bridgedb/test/test_Dist.py @@ -0,0 +1,245 @@ +# -*- coding: utf-8 -*- +# +# This file is part of BridgeDB, a Tor bridge distribution system. +# +# :authors: Isis Lovecruft 0xA3ADB67A2CDB8B35 +# please also see AUTHORS file +# :copyright: (c) 2013-2015 Isis Lovecruft +# (c) 2007-2015, The Tor Project, Inc. +# (c) 2007-2015, all entities within the AUTHORS file +# :license: 3-clause BSD, see included LICENSE for information + +"""Tests for :mod:`bridgedb.Dist`.""" + +from __future__ import print_function + +import hashlib +import ipaddr +import random + +from twisted.trial import unittest + +from bridgedb import Dist +from bridgedb.bridges import Bridge +from bridgedb.bridges import PluggableTransport +from bridgedb.Bridges import BridgeRing +from bridgedb.Filters import filterBridgesByNotBlockedIn +from bridgedb.https.request import HTTPSBridgeRequest +from bridgedb.proxy import ProxySet +from bridgedb.test.util import randomHighPort +from bridgedb.test.util import randomValidIPv4String +from bridgedb.test.util import randomValidIPv6 +from bridgedb.test.https_helpers import DummyRequest + + +def _generateFakeBridges(n=500): +bridges = [] + +for i in range(n): +addr = randomValidIPv4String() +nick = 'bridge-%d' % i +port = randomHighPort() +# Real tor currently only supports one extra ORAddress, and it can +# only be IPv6. +addrs = [(randomValidIPv6(), randomHighPort(), 6)] +fpr = "".join(random.choice('abcdef0123456789') for _ in xrange(40)) + +# We only support the ones without PT args, because they're easier to fake. +supported = ["obfs2", "obfs3", "fte"] +transports = [] +for j, method in zip(range(1, len(supported) + 1), supported): +pt = PluggableTransport(fpr, method, addr, port - j, {}) +transports.append(pt) + +bridge = Bridge(nick, addr, port, fpr) +bridge.flags.update("Running Stable") +bridge.transports = transports +bridge.orAddresses = addrs +bridges.append(bridge) + +return bridges + + +BRIDGES = _generateFakeBridges() + + +class GetNumBridgesPerAnswerTests(unittest.TestCase): +"""Unittests for :func:`bridgedb.Dist.getNumBridgesPerAnswer`.""" + +def setUp(self): +self.key = 'aQpeOFIj8q20s98awfoiq23rpOIjFaqpEWFoij1X' +self.ring = BridgeRing(self.key) +self.bridges = _generateFakeBridges() + +def test_Dist_getNumBridgesPerAnswer_120(self): +[self.ring.insert(bridge) for bridge in self.bridges[:120]] +self.assertEqual(Dist.getNumBridgesPerAnswer(self.ring), 3) + +def test_Dist_getNumBridgesPerAnswer_100(self): +[self.ring.insert(bridge) for bridge in self.bridges[:100]] +self.assertEqual(Dist.getNumBridgesPerAnswer(self.ring), 3) + +def test_Dist_getNumBridgesPerAnswer_50(self): +[self.ring.insert(bridge) for bridge in self.bridges[:60]] +self.assertEqual(Dist.getNumBridgesPerAnswer(self.ring), 2) + +def test_Dist_getNumBridgesPerAnswer_15(self): +[self.ring.insert(bridge) for bridge in self.bridges[:15]] +self.assertEqual(Dist.getNumBridgesPerAnswer(self.ring), 1) + +def test_Dist_getNumBridgesPerAnswer_100_max_5(self): +[self.ring.insert(bridge) for bridge in self.bridges[:100]] +self.assertEqual( +Dist.getNumBridgesPerAnswer(self.ring, max_bridges_per_answer=5), +5) + + +class HTTPSDistributorTests(unittest.TestCase): +"""Tests for :class:`HTTPSDistributor`.""" + +def setUp(self): +self.key = 'aQpeOFIj8q20s98awfoiq23rpOIjFaqpEWFoij1X' +self.bridges = BRIDGES + +def tearDown(self): +"""Reset all bridge blocks in between test method runs.""" +for bridge in self.bridges: +bridge._blockedIn = {} + +def coinFlip(self): +return bool(random.getrandbits(1)) + +def randomClientRequest(self): +bridgeRequest = HTTPSBridgeRequest(addClientCountryCode=False) +bridgeRequest.client = randomValidIPv4String() +bridgeRequest.isValid(True) +bridgeRequest.generateFilters() +return bridgeRequest + +def randomClientRequestForNotBlockedIn(self, cc): +httpRequest = DummyRequest(['']) +httpRequest.args.update({'unblocked': [cc]}) +bridgeRequest = self.randomClientRequest() +bridgeRequest.withoutBlockInCountry(httpRequest) +bridgeRequest.generateFilters() +return bridgeRequest + +def test_HTTPSDi
[tor-commits] [bridgedb/develop] Teach Bridge._getVanillaForRequest() to filter blocked addresses.
commit 53c8e7a1aefc6a25c3a7cdc56d19c62137ad4066 Author: Isis Lovecruft Date: Sat Apr 18 03:28:31 2015 + Teach Bridge._getVanillaForRequest() to filter blocked addresses. --- lib/bridgedb/bridges.py | 36 +--- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/lib/bridgedb/bridges.py b/lib/bridgedb/bridges.py index c8c7a30..8f4f853 100644 --- a/lib/bridgedb/bridges.py +++ b/lib/bridgedb/bridges.py @@ -997,6 +997,10 @@ class Bridge(BridgeBackwardsCompatibility): return address, port, version = addrport + +if not address or not port: +return + bridgeLine = [] if bridgePrefix: @@ -1094,26 +1098,28 @@ class Bridge(BridgeBackwardsCompatibility): "Bridge %s answering request for IPv%s vanilla address..." % (self, "6" if bridgeRequest.addressClass is ipaddr.IPv6Address else "4")) -if not bridgeRequest.filters: -logging.debug(("Request %s didn't have any filters; " - "generating them now...") % bridgeRequest) -bridgeRequest.generateFilters() +addresses = [] -addresses = self.allVanillaAddresses - -# Filter ``allVanillaAddresses`` by whether IPv4 or IPv6 was requested: -addresses = filter( -# ``address`` here is a 3-tuple: -# ``(ipaddr.IPAddress, int(port), int(ipaddr.IPAddress.version))`` -lambda address: isinstance(address[0], bridgeRequest.addressClass), -self.allVanillaAddresses) +for address, port, version in self.allVanillaAddresses: +# Filter ``allVanillaAddresses`` by whether IPv4 or IPv6 was requested: +if isinstance(address, bridgeRequest.addressClass): +# Determine if the address is blocked in any of the country +# codes. Because :meth:`addressIsBlockedIn` returns a bool, +# we get a list like: ``[True, False, False, True]``, and +# because bools are ints, they may be summed. What we care +# about is that there are no ``True``s, for any country code, +# so we check that the sum is zero (meaning the list was full +# of ``False``s). +# +# XXX Do we want to add a method for this construct? +if not sum([self.addressIsBlockedIn(cc, address, port) +for cc in bridgeRequest.notBlockedIn]): +addresses.append((address, port, version)) if addresses: # Use the client's unique data to HMAC them into their position in # the hashring of filtered bridges addresses: -position = bridgeRequest.getHashringPlacement('Order-Or-Addresses', - bridgeRequest.client) -logging.debug("Client's hashring position is %r" % position) +position = bridgeRequest.getHashringPlacement('Order-Or-Addresses') vanilla = addresses[position % len(addresses)] logging.info("Got vanilla bridge for client.") ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Add bridgedb.distribute module with IDistribute and Distributor classes.
commit fe0efec8b00250756d36c7fb2cd061fd8ef3d3d3 Author: Isis Lovecruft Date: Sun Apr 19 00:05:02 2015 + Add bridgedb.distribute module with IDistribute and Distributor classes. * ADD distribute.IDistibute interface. * ADD distribute.Distributor class, an implementation of IDistribute. * REMOVE bridgedb.Dist.Distributor. * RENAME HTTPSDistributor.getBridgesForIP() â HTTPSDistributor.getBridges(). * RENAME EmailBasedDistributor.getBridgesForEmail() â EmailBasedDistributor.getBridges(). * FIXES part of #12506: https://bugs.torproject.org/12506 * FIXES part of #12029: https://bugs.torproject.org/12029 --- lib/bridgedb/Dist.py | 104 +++-- lib/bridgedb/distribute.py | 275 ++ lib/bridgedb/email/autoresponder.py |5 +- lib/bridgedb/interfaces.py | 56 ++- lib/bridgedb/test/email_helpers.py | 10 +- lib/bridgedb/test/https_helpers.py |2 +- lib/bridgedb/test/legacy_Tests.py| 64 lib/bridgedb/test/test_Dist.py | 11 +- lib/bridgedb/test/test_distribute.py | 44 ++ lib/bridgedb/test/test_interfaces.py | 55 +++ 10 files changed, 495 insertions(+), 131 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 93c08c1..fe81c04 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -17,20 +17,19 @@ import logging import re import time -import bridgedb.Bridges import bridgedb.Storage from bridgedb import proxy +from bridgedb.Bridges import BridgeRing from bridgedb.Bridges import FilteredBridgeSplitter from bridgedb.crypto import getHMAC from bridgedb.crypto import getHMACFunc +from bridgedb.distribute import Distributor from bridgedb.Filters import filterAssignBridgesToRing from bridgedb.Filters import filterBridgesByRules from bridgedb.Filters import filterBridgesByIP4 from bridgedb.Filters import filterBridgesByIP6 from bridgedb.parse import addr -from bridgedb.parse.addr import UnsupportedDomain -from bridgedb.safelog import logSafely MAX_EMAIL_RATE = 3*3600 @@ -48,50 +47,6 @@ class EmailRequestedKey(Exception): """Raised when an incoming email requested a copy of our GnuPG keys.""" -class Distributor(object): -"""Distributes bridges to clients.""" - -def __init__(self): -super(Distributor, self).__init__() -self.name = None -self.hashring = None - -def setDistributorName(self, name): -"""Set a **name** for identifying this distributor. - -This is used to identify the distributor in the logs; the **name** -doesn't necessarily need to be unique. The hashrings created for this -distributor will be named after this distributor's name in -:meth:`propopulateRings`, and any sub hashrings of each of those -hashrings will also carry that name. - ->>> from bridgedb import Dist ->>> dist = Dist.HTTPSDistributor(2, 'masterkey') ->>> dist.setDistributorName('Excellent Distributor') ->>> dist.name -'Excellent Distributor' - -:param str name: A name for this distributor. -""" -self.name = name -self.hashring.distributorName = name - -def bridgesPerResponse(self, hashring=None, maximum=3): -if hashring is None: -hashring = self.hashring - -if len(hashring) < 20: -n = 1 -if 20 <= len(hashring) < 100: -n = min(2, maximum) -if len(hashring) >= 100: -n = maximum - -logging.debug("Returning %d bridges from ring of len: %d" % - (n, len(hashring))) -return n - - class HTTPSDistributor(Distributor): """A Distributor that hands out bridges based on the IP address of an incoming request and the current time period. @@ -129,9 +84,7 @@ class HTTPSDistributor(Distributor): parameters, i.e. that an answer has "at least two obfsproxy bridges" or "at least one bridge on port 443", etc. """ -super(HTTPSDistributor, self).__init__() - -self.key = key +super(HTTPSDistributor, self).__init__(key) self.totalSubrings = totalSubrings self.answerParameters = answerParameters @@ -154,13 +107,12 @@ class HTTPSDistributor(Distributor): self._clientToPositionHMAC = getHMACFunc(key3, hex=False) self._subnetToSubringHMAC = getHMACFunc(key4, hex=True) self.hashring = FilteredBridgeSplitter(key2, self.ringCacheSize) -logging.debug("Added %s to HTTPS distributor." % - self.hashring.__class__.__name__) +self.name = 'HTTPS' +logging.debug("Added %s to %s distributor." % + (self.hashring.__class__.__name__, self.name)) -self.setDistributorName('HTTPS') - -def bridgesPerResponse(
[bridgedb/develop] Rename IPBasedDistributor → HTTPSDistributor.
commit ae7acb11669b380de4f7873857ca30167cd493b9 Author: Isis Lovecruft Date: Thu Apr 16 05:44:32 2015 + Rename IPBasedDistributor â HTTPSDistributor. --- lib/bridgedb/Bridges.py|2 +- lib/bridgedb/Dist.py | 25 + lib/bridgedb/Main.py |6 +++--- lib/bridgedb/bridges.py|2 +- lib/bridgedb/https/request.py |2 +- lib/bridgedb/https/server.py |4 ++-- lib/bridgedb/test/https_helpers.py |4 ++-- lib/bridgedb/test/legacy_Tests.py | 20 ++-- lib/bridgedb/test/test_Main.py | 10 +- lib/bridgedb/test/test_https_server.py |6 +++--- 10 files changed, 41 insertions(+), 40 deletions(-) diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py index a13a73e..b8fdd2e 100644 --- a/lib/bridgedb/Bridges.py +++ b/lib/bridgedb/Bridges.py @@ -523,7 +523,7 @@ class FilteredBridgeSplitter(BridgeHolder): :ivar bridges: DOCDOC :type distributorName: str :ivar distributorName: The name of this splitter's distributor. See - :meth:`bridgedb.Dist.IPBasedDistributor.setDistributorName`. + :meth:`bridgedb.Dist.HTTPSDistributor.setDistributorName`. """ self.key = key self.filterRings = {} diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index ff9a85d..e66c1e6 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -67,6 +67,7 @@ class Distributor(object): def __init__(self): super(Distributor, self).__init__() +self.name = None def setDistributorName(self, name): """Set a **name** for identifying this distributor. @@ -78,12 +79,10 @@ class Distributor(object): hashrings will also carry that name. >>> from bridgedb import Dist ->>> ipDist = Dist.IPBasedDistributor(5, 'fake-hmac-key') ->>> ipDist.setDistributorName('HTTPS Distributor') ->>> ipDist.prepopulateRings() ->>> hashrings = ipDist.hashring.filterRings ->>> firstSubring = hashrings.items()[0][1][1] ->>> assert firstSubring.name +>>> dist = Dist.HTTPSDistributor(2, 'masterkey') +>>> dist.setDistributorName('Excellent Distributor') +>>> dist.name +'Excellent Distributor' :param str name: A name for this distributor. """ @@ -91,7 +90,7 @@ class Distributor(object): self.hashring.distributorName = name -class IPBasedDistributor(Distributor): +class HTTPSDistributor(Distributor): """A Distributor that hands out bridges based on the IP address of an incoming request and the current time period. @@ -128,6 +127,8 @@ class IPBasedDistributor(Distributor): parameters, i.e. that an answer has "at least two obfsproxy bridges" or "at least one bridge on port 443", etc. """ +super(HTTPSDistributor, self).__init__() + self.key = key self.totalSubrings = totalSubrings self.answerParameters = answerParameters @@ -171,14 +172,14 @@ class IPBasedDistributor(Distributor): ``1.2.178.234``) are placed within the same cluster, but Carol (with address ``1.3.11.33``) *might* end up in a different cluster. ->>> from bridgedb.Dist import IPBasedDistributor ->>> IPBasedDistributor.getSubnet('1.2.3.4') +>>> from bridgedb.Dist import HTTPSDistributor +>>> HTTPSDistributor.getSubnet('1.2.3.4') '1.2.0.0/16' ->>> IPBasedDistributor.getSubnet('1.2.211.154') +>>> HTTPSDistributor.getSubnet('1.2.211.154') '1.2.0.0/16' ->>> IPBasedDistributor.getSubnet('2001:f::bc1:b13:2808') +>>> HTTPSDistributor.getSubnet('2001:f::bc1:b13:2808') '2001:f::/32' ->>> IPBasedDistributor.getSubnet('2a00:c98:2030:a020:2::42') +>>> HTTPSDistributor.getSubnet('2a00:c98:2030:a020:2::42') '2a00:c98::/32' :param str ip: A string representing an IPv4 or IPv6 address. diff --git a/lib/bridgedb/Main.py b/lib/bridgedb/Main.py index 1262122..0bb319d 100644 --- a/lib/bridgedb/Main.py +++ b/lib/bridgedb/Main.py @@ -194,7 +194,7 @@ def createBridgeRings(cfg, proxyList, key): known open proxies. :param bytes key: Hashring master key :rtype: tuple -:returns: A BridgeSplitter hashring, an IPBasedDistributor or None, +:returns: A BridgeSplitter hashring, an HTTPSDistributor or None, and an EmailBasedDistributor or None. """ # Create a BridgeSplitter to assign the bridges to the different @@ -210,7 +210,7 @@ def createBridgeRings(cfg, proxyList, key): # As appropriate, create an IP-based distributor. if cfg.HTTPS_DIST and cfg.HTTPS_SHARE: logging.debug("Setting up HTTPS Distributor...") -ipDistributor = Dist.IPBasedDistributor( +ipDistributor = Dist.HTTPSDistributor(
[tor-commits] [bridgedb/develop] Make subhashring cache size relative to numberOfClusters.
commit 397cc7d316a618bcadfca6663f318d3b798f4405 Author: Isis Lovecruft Date: Sat Apr 11 02:53:20 2015 + Make subhashring cache size relative to numberOfClusters. * RENAME ring_cache_size â IPBasedDistributor.ringCacheSize. * CHANGE IPBasedDistributor.ringCacheSize to be relative to the total number of clusters, rather than equal to the total number of clusters plus five. --- lib/bridgedb/Dist.py | 19 +++ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 129bc7c..1a01543 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -21,6 +21,7 @@ import bridgedb.Bridges import bridgedb.Storage from bridgedb import proxy +from bridgedb.Bridges import FilteredBridgeSplitter from bridgedb.crypto import getHMAC from bridgedb.crypto import getHMACFunc from bridgedb.Filters import filterAssignBridgesToRing @@ -193,23 +194,17 @@ class IPBasedDistributor(Distributor): self.proxies = proxy.ProxySet() self.proxyCluster = 0 +self.ringCacheSize = self.numberOfClusters * 3 key2 = getHMAC(key, "Assign-Bridges-To-Rings") key3 = getHMAC(key, "Order-Areas-In-Rings") -self.areaOrderHmac = getHMACFunc(key3, hex=False) key4 = getHMAC(key, "Assign-Areas-To-Rings") -self.areaClusterHmac = getHMACFunc(key4, hex=True) -# add splitter and cache the default rings -# plus leave room for dynamic filters -# -# XXX Why is the "extra room" hardcoded to be 5? Shouldn't it be some -# fraction of the number of clusters/categories? --isis -ring_cache_size = self.numberOfClusters + 5 -self.splitter = bridgedb.Bridges.FilteredBridgeSplitter( -key2, max_cached_rings=ring_cache_size) -logging.debug("Added splitter %s to IPBasedDistributor." - % self.splitter.__class__) +self.areaOrderHmac = getHMACFunc(key3, hex=False) +self.areaClusterHmac = getHMACFunc(key4, hex=True) +self.splitter = FilteredBridgeSplitter(key2, self.ringCacheSize) +logging.debug("Added %s to HTTPS distributor." % + self.splitter.__class__.__name__) self.setDistributorName('HTTPS') ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[bridgedb/develop] Remove most "splitter"s — they're just crappy consistent hashrings.
commit d83438d24104c5834cd0230a757b17a8e1941edb Author: Isis Lovecruft Date: Tue Apr 14 09:23:40 2015 + Remove most "splitter"sâââthey're just crappy consistent hashrings. --- lib/bridgedb/Bridges.py |2 +- lib/bridgedb/Dist.py | 60 ++-- lib/bridgedb/Main.py | 66 +++--- lib/bridgedb/test/legacy_Tests.py |4 +- lib/bridgedb/test/test_Main.py| 80 ++--- lib/bridgedb/test/test_bridges.py | 24 +-- 6 files changed, 118 insertions(+), 118 deletions(-) diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py index c727c9a..b06ffc4 100644 --- a/lib/bridgedb/Bridges.py +++ b/lib/bridgedb/Bridges.py @@ -569,7 +569,7 @@ class FilteredBridgeSplitter(BridgeHolder): return index = 0 -logging.debug("Inserting %s into splitter" +logging.debug("Inserting %s into hashring" % (logSafely(bridge.fingerprint))) for old_bridge in self.bridges[:]: if bridge.fingerprint == old_bridge.fingerprint: diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 445d2d8..44cb526 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -81,14 +81,14 @@ class Distributor(object): >>> ipDist = Dist.IPBasedDistributor(5, 'fake-hmac-key') >>> ipDist.setDistributorName('HTTPS Distributor') >>> ipDist.prepopulateRings() ->>> hashrings = ipDist.splitter.filterRings +>>> hashrings = ipDist.hashring.filterRings >>> firstSubring = hashrings.items()[0][1][1] >>> assert firstSubring.name :param str name: A name for this distributor. """ self.name = name -self.splitter.distributorName = name +self.hashring.distributorName = name class IPBasedDistributor(Distributor): @@ -98,8 +98,8 @@ class IPBasedDistributor(Distributor): :type proxies: :class:`~bridgedb.proxies.ProxySet` :ivar proxies: All known proxies, which we treat differently. See :param:`proxies`. -:type splitter: :class:`bridgedb.Bridges.FixedBridgeSplitter` -:ivar splitter: A hashring that assigns bridges to subrings with fixed +:type hashring: :class:`bridgedb.Bridges.FixedBridgeSplitter` +:ivar hashring: A hashring that assigns bridges to subrings with fixed proportions. Used to assign bridges into the subrings of this distributor. """ @@ -150,9 +150,9 @@ class IPBasedDistributor(Distributor): self._clientToPositionHMAC = getHMACFunc(key3, hex=False) self._subnetToSubringHMAC = getHMACFunc(key4, hex=True) -self.splitter = FilteredBridgeSplitter(key2, self.ringCacheSize) +self.hashring = FilteredBridgeSplitter(key2, self.ringCacheSize) logging.debug("Added %s to HTTPS distributor." % - self.splitter.__class__.__name__) + self.hashring.__class__.__name__) self.setDistributorName('HTTPS') @@ -311,16 +311,16 @@ class IPBasedDistributor(Distributor): # distributor's proxies: if subring == self.proxySubring: ring.setName('{0} Proxy Ring'.format(self.name)) -self.splitter.addRing(ring, filters, +self.hashring.addRing(ring, filters, filterBridgesByRules(filters), - populate_from=self.splitter.bridges) + populate_from=self.hashring.bridges) def insert(self, bridge): """Assign a bridge to this distributor.""" -self.splitter.insert(bridge) +self.hashring.insert(bridge) def _buildHashringFilters(self, previousFilters, subring): -f = filterAssignBridgesToRing(self.splitter.hmac, self.totalSubrings, subring) +f = filterAssignBridgesToRing(self.hashring.hmac, self.totalSubrings, subring) previousFilters.append(f) return frozenset(previousFilters) @@ -343,8 +343,8 @@ class IPBasedDistributor(Distributor): logging.info("Attempting to return %d bridges to client %s..." % (N, bridgeRequest.client)) -if not len(self.splitter): -logging.warn("Bailing! Splitter has zero bridges!") +if not len(self.hashring): +logging.warn("Bailing! Hashring has zero bridges!") return [] usingProxy = False @@ -373,16 +373,16 @@ class IPBasedDistributor(Distributor): logging.debug("Bridge filters: %s" % ' '.join([x.func_name for x in filters])) # Check wheth we have a cached copy of the hashring: -if filters in self.splitter.filterRings.keys(): +if filters in self.hashring.filterRings.keys(): logging.debug("Cache hit %s" % filters) -_, ring = self.splitter.filterRings[filters
[tor-commits] [bridgedb/develop] Change all distributors to store their own keys.
commit d5628d5bb6244e7f8a0cbd30fa1e52941eb91867 Author: Isis Lovecruft Date: Tue Apr 14 09:11:21 2015 + Change all distributors to store their own keys. --- lib/bridgedb/Dist.py | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 58f0a2d..445d2d8 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -128,6 +128,7 @@ class IPBasedDistributor(Distributor): parameters, i.e. that an answer has "at least two obfsproxy bridges" or "at least one bridge on port 443", etc. """ +self.key = key self.totalSubrings = totalSubrings self.answerParameters = answerParameters @@ -303,7 +304,7 @@ class IPBasedDistributor(Distributor): for filterFn in [filterBridgesByIP4, filterBridgesByIP6]: for subring in range(1, self.totalSubrings + 1): filters = self._buildHashringFilters([filterFn,], subring) -key1 = getHMAC(self.splitter.key, "Order-Bridges-In-Ring-%d" % subring) +key1 = getHMAC(self.key, "Order-Bridges-In-Ring-%d" % subring) ring = bridgedb.Bridges.BridgeRing(key1, self.answerParameters) # For consistency with previous implementation of this method, # only set the "name" for "clusters" which are for this @@ -378,7 +379,7 @@ class IPBasedDistributor(Distributor): # Otherwise, construct a new hashring and populate it: else: logging.debug("Cache miss %s" % filters) -key1 = getHMAC(self.splitter.key, "Order-Bridges-In-Ring-%d" % subring) +key1 = getHMAC(self.key, "Order-Bridges-In-Ring-%d" % subring) ring = bridgedb.Bridges.BridgeRing(key1, self.answerParameters) self.splitter.addRing(ring, filters, filterBridgesByRules(filters), populate_from=self.splitter.bridges) @@ -420,6 +421,8 @@ class EmailBasedDistributor(Distributor): :param whitelist: A dictionary that maps whitelisted email addresses to GnuPG fingerprints. """ +self.key = key + key1 = getHMAC(key, "Map-Addresses-To-Ring") self.emailHmac = getHMACFunc(key1, hex=False) @@ -505,7 +508,7 @@ class EmailBasedDistributor(Distributor): logging.debug("Cache miss %s" % ruleset) # add new ring -key1 = getHMAC(self.splitter.key, "Order-Bridges-In-Ring") +key1 = getHMAC(self.key, "Order-Bridges-In-Ring") ring = bridgedb.Bridges.BridgeRing(key1, self.answerParameters) self.splitter.addRing(ring, ruleset, filterBridgesByRules(ruleset), @@ -541,7 +544,7 @@ class EmailBasedDistributor(Distributor): # populate all rings (for dumping assignments and testing) for filterFn in [filterBridgesByIP4, filterBridgesByIP6]: ruleset = frozenset([filterFn]) -key1 = getHMAC(self.splitter.key, "Order-Bridges-In-Ring") +key1 = getHMAC(self.key, "Order-Bridges-In-Ring") ring = bridgedb.Bridges.BridgeRing(key1, self.answerParameters) self.splitter.addRing(ring, ruleset, filterBridgesByRules([filterFn]), ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Make `areaMapper` built into the IPBasedDistributor class.
commit 34a97ccc019ca5b9956b8566d81d893293ae5f00 Author: Isis Lovecruft Date: Tue Apr 14 07:12:23 2015 + Make `areaMapper` built into the IPBasedDistributor class. * MOVE Dist.uniformMap() â Dist.IPBasedDistributor.getSubnet(). * REMOVE IPBasedDistributor `areaMapper` parameter. * RENAME IPBasedDistributor.areaOrderHmac â IPBasedDistributor._clientToPositionHMAC. * RENAME IPBasedDistributor.areaClusterHmac â IPBasedDistributor._subnetToSubringHMAC. * ADD IPBasedDistributor.mapClientToHashringPosition() to replace and simplify inline use of IPBasedDistributor._clientToPositionHMAC. * ADD IPBasedDistributor.mapSubnetToSubring() to replace and simplify inline use of IPBasedDistributor._subnetToSubringHMAC. --- lib/bridgedb/Dist.py | 184 ++ lib/bridgedb/Main.py |1 - 2 files changed, 111 insertions(+), 74 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 1a01543..082f002 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -48,39 +48,6 @@ class EmailRequestedKey(Exception): """Raised when an incoming email requested a copy of our GnuPG keys.""" -def uniformMap(ip): -"""Map an IP to an arbitrary 'area' string, such that any two IPv4 -addresses in the same ``/16`` subnet, or any two IPv6 addresses in the -same ``/32`` subnet, get the same string. - ->>> from bridgedb import Dist ->>> Dist.uniformMap('1.2.3.4') -'1.2.0.0/16' ->>> Dist.uniformMap('1.2.211.154') -'1.2.0.0/16' ->>> Dist.uniformMap('2001:f::bc1:b13:2808') -'2001:f::/32' ->>> Dist.uniformMap('2a00:c98:2030:a020:2::42') -'2a00:c98::/32' - -:param str ip: A string representing an IPv4 or IPv6 address. -:rtype: str -:returns: The appropriately sized CIDR subnet representation of the **ip**. -""" -# We aren't using bridgedb.parse.addr.isIPAddress(ip, compressed=False) -# here because adding the string "False" into the map would land any and -# all clients whose IP address appeared to be invalid at the same position -# in a hashring. -address = ipaddr.IPAddress(ip) -if address.version == 6: -truncated = ':'.join(address.exploded.split(':')[:2]) -subnet = str(ipaddr.IPv6Network(truncated + "::/32")) -return subnet -else: -truncated = '.'.join(address.exploded.split('.')[:2]) -subnet = str(ipaddr.IPv4Network(truncated + '.0.0/16')) -return subnet - def getNumBridgesPerAnswer(ring, max_bridges_per_answer=3): if len(ring) < 20: n_bridges_per_answer = 1 @@ -111,9 +78,7 @@ class Distributor(object): hashrings will also carry that name. >>> from bridgedb import Dist ->>> ipDist = Dist.IPBasedDistributor(Dist.uniformMap, -... 5, -... 'fake-hmac-key') +>>> ipDist = Dist.IPBasedDistributor(5, 'fake-hmac-key') >>> ipDist.setDistributorName('HTTPS Distributor') >>> ipDist.prepopulateRings() >>> hashrings = ipDist.splitter.filterRings @@ -130,8 +95,6 @@ class IPBasedDistributor(Distributor): """A Distributor that hands out bridges based on the IP address of an incoming request and the current time period. -:ivar areaOrderHmac: An HMAC function used to order areas within rings. -:ivar areaClusterHmac: An HMAC function used to assign areas to rings. :ivar list rings: A list of :class:`bridgedb.Bridges.BridgeHolder` hashrings, one for each area in the ``areaMapper``. Every inserted bridge will go into one of these rings, and every area is associated @@ -145,19 +108,10 @@ class IPBasedDistributor(Distributor): distributor. """ -def __init__(self, areaMapper, numberOfClusters, key, - proxies=None, answerParameters=None): +def __init__(self, numberOfClusters, key, proxies=None, answerParameters=None): """Create a Distributor that decides which bridges to distribute based upon the client's IP address and the current time. -:type areaMapper: callable -:param areaMapper: A function that maps IP addresses arbitrarily to -strings, such that IP addresses which map to identical strings are -considered to be in the same "area". The default **areaMapper** -is :func:`bridgedb.Dist.uniformMap`, which maps all IPv4 addresses -within the same /16 and all IPv6 addresses within the same /32 to -the same area. Areas are then grouped into the number of rings -specified by the ``N_IP_CLUSTERS`` configuration option. :param integer numberOfClusters: The number of clusters to group IP addresses into. Note that if PROXY_LIST_FILES is set in bridgedb.conf
[tor-commits] [bridgedb/develop] Remove the idea of clusters. Clusters are just subhashrings.
commit 1a676f343a7a5a854106c9e90c8418d1f7b2c09e Author: Isis Lovecruft Date: Tue Apr 14 07:33:38 2015 + Remove the idea of clusters. Clusters are just subhashrings. --- lib/bridgedb/Dist.py| 60 +++ lib/bridgedb/Filters.py |2 +- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index c9d82c1..58f0a2d 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -104,16 +104,15 @@ class IPBasedDistributor(Distributor): distributor. """ -def __init__(self, numberOfClusters, key, proxies=None, answerParameters=None): +def __init__(self, totalSubrings, key, proxies=None, answerParameters=None): """Create a Distributor that decides which bridges to distribute based upon the client's IP address and the current time. -:param integer numberOfClusters: The number of clusters to group IP addresses -into. Note that if PROXY_LIST_FILES is set in bridgedb.conf, then -the actual number of clusters is one higher than ``numberOfClusters``, -because the set of known open proxies constitutes its own -category. -DOCDOC What exactly does a cluster *do*? +:param int totalSubrings: The number of subhashrings to group clients +into. Note that if ``PROXY_LIST_FILES`` is set in bridgedb.conf, +then the actual number of clusters is one higher than +``totalSubrings``, because the set of all known open proxies is +given its own subhashring. :param bytes key: The master HMAC key for this distributor. All added bridges are HMACed with this key in order to place them into the hashrings. @@ -129,20 +128,20 @@ class IPBasedDistributor(Distributor): parameters, i.e. that an answer has "at least two obfsproxy bridges" or "at least one bridge on port 443", etc. """ +self.totalSubrings = totalSubrings self.answerParameters = answerParameters -self.numberOfClusters = numberOfClusters if proxies: logging.info("Added known proxies to HTTPS distributor...") self.proxies = proxies -self.numberOfClusters += 1 -self.proxyCluster = self.numberOfClusters +self.totalSubrings += 1 +self.proxySubring = self.totalSubrings else: logging.warn("No known proxies were added to HTTPS distributor!") self.proxies = proxy.ProxySet() -self.proxyCluster = 0 +self.proxySubring = 0 -self.ringCacheSize = self.numberOfClusters * 3 +self.ringCacheSize = self.totalSubrings * 3 key2 = getHMAC(key, "Assign-Bridges-To-Rings") key3 = getHMAC(key, "Order-Areas-In-Rings") @@ -223,13 +222,13 @@ class IPBasedDistributor(Distributor): # If the client wasn't using a proxy, select the client's subring # based upon the client's subnet (modulo the total subrings): if not usingProxy: -mod = self.numberOfClusters +mod = self.totalSubrings # If there is a proxy subring, don't count it for the modulus: -if self.proxyCluster: +if self.proxySubring: mod -= 1 -return int(self._subnetToSubringHMAC(subnet)[:8], 16) % mod +return (int(self._subnetToSubringHMAC(subnet)[:8], 16) % mod) + 1 else: -return self.proxyCluster +return self.proxySubring def mapClientToHashringPosition(self, interval, subnet): """Map the client to a position on a (sub)hashring, based upon the @@ -260,14 +259,14 @@ class IPBasedDistributor(Distributor): ``N_IP_CLUSTERS`` configuration option, as well as the number of ``PROXY_LIST_FILES``. -Essentially, :data:`numberOfClusters` is set to the specified +Essentially, :data:`totalSubrings` is set to the specified ``N_IP_CLUSTERS``. All of the ``PROXY_LIST_FILES``, plus the list of Tor Exit relays (downloaded into memory with :script:`get-tor-exits`), are stored in :data:`proxies`, and the latter is added as an -additional cluster (such that :data:`numberOfClusters` becomes +additional cluster (such that :data:`totalSubrings` becomes ``N_IP_CLUSTERS + 1``). The number of subhashrings which this :class:`Distributor` has active in its hashring is then -:data:`numberOfClusters`, where the last cluster is reserved for all +:data:`totalSubrings`, where the last cluster is reserved for all :data:`proxies`. As an example, if BridgeDB was configured with ``N_IP_CLUSTERS=4`` and @@ -302,14 +301,14 @@ class IPBasedDistributor(Distributor): logging.info("Prepopulating %s distributor hashrings..." % self.n
[tor-commits] [bridgedb/develop] Update documentation on IPBasedDistributor area mapping.
commit 33cb6c45d12d83c441595ff0fc2bf6cc21e46623 Author: Isis Lovecruft Date: Sat Apr 11 02:52:31 2015 + Update documentation on IPBasedDistributor area mapping. --- lib/bridgedb/Dist.py | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index ab7ae6e..129bc7c 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -151,9 +151,12 @@ class IPBasedDistributor(Distributor): :type areaMapper: callable :param areaMapper: A function that maps IP addresses arbitrarily to -strings, such that addresses which map to identical strings are -considered to be in the same "area" (for some arbitrary definition -of "area"). See :func:`bridgedb.Dist.uniformMap` for an example. +strings, such that IP addresses which map to identical strings are +considered to be in the same "area". The default **areaMapper** +is :func:`bridgedb.Dist.uniformMap`, which maps all IPv4 addresses +within the same /16 and all IPv6 addresses within the same /32 to +the same area. Areas are then grouped into the number of rings +specified by the ``N_IP_CLUSTERS`` configuration option. :param integer numberOfClusters: The number of clusters to group IP addresses into. Note that if PROXY_LIST_FILES is set in bridgedb.conf, then the actual number of clusters is one higher than ``numberOfClusters``, @@ -327,8 +330,6 @@ class IPBasedDistributor(Distributor): # based upon the client's area (i.e. the /16 of the client's IP # address): else: -# Areas (i.e. /16s) are grouped into the number of rings specified -# by the N_IP_CLUSTERS configuration option. area = self.areaMapper(bridgeRequest.client) cluster = (int(self.areaClusterHmac(area)[:8], 16) % (self.numberOfClusters - 1)) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Remove IPBasedDistributor.rings.
commit 809f447f3c8a7e0023a399de469b77a8b4c2735f Author: Isis Lovecruft Date: Tue Apr 14 07:25:45 2015 + Remove IPBasedDistributor.rings. It was never used. --- lib/bridgedb/Dist.py |5 - 1 file changed, 5 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 082f002..c9d82c1 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -95,10 +95,6 @@ class IPBasedDistributor(Distributor): """A Distributor that hands out bridges based on the IP address of an incoming request and the current time period. -:ivar list rings: A list of :class:`bridgedb.Bridges.BridgeHolder` -hashrings, one for each area in the ``areaMapper``. Every inserted -bridge will go into one of these rings, and every area is associated -with one. :type proxies: :class:`~bridgedb.proxies.ProxySet` :ivar proxies: All known proxies, which we treat differently. See :param:`proxies`. @@ -133,7 +129,6 @@ class IPBasedDistributor(Distributor): parameters, i.e. that an answer has "at least two obfsproxy bridges" or "at least one bridge on port 443", etc. """ -self.rings = [] self.answerParameters = answerParameters self.numberOfClusters = numberOfClusters ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Whitespace fixes in bridgedb.https.server module.
commit e62191b6d484074d3d1fa30ef0cd4906822eaf2c Author: Isis Lovecruft Date: Thu Apr 16 05:10:47 2015 + Whitespace fixes in bridgedb.https.server module. --- lib/bridgedb/https/server.py | 106 +- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/lib/bridgedb/https/server.py b/lib/bridgedb/https/server.py index ab15ef3..6010218 100644 --- a/lib/bridgedb/https/server.py +++ b/lib/bridgedb/https/server.py @@ -6,8 +6,8 @@ # :copyright: (c) 2007-2015, The Tor Project, Inc. # (c) 2013-2015, Isis Lovecruft # :license: see LICENSE for licensing information - -""" + +""" .. py:module:: bridgedb.https.server :synopsis: Servers which interface with clients and distribute bridges over HTTP(S). @@ -16,16 +16,16 @@ bridgedb.https.server = Servers which interface with clients and distribute bridges over HTTP(S). -""" - -import base64 -import gettext -import logging +""" + +import base64 +import gettext +import logging import random -import re -import time -import os - +import re +import time +import os + from functools import partial from ipaddr import IPv4Address @@ -34,14 +34,14 @@ import mako.exceptions from mako.template import Template from mako.lookup import TemplateLookup -from twisted.internet import reactor +from twisted.internet import reactor from twisted.internet.error import CannotListenError from twisted.web import resource -from twisted.web import static +from twisted.web import static from twisted.web.server import NOT_DONE_YET from twisted.web.server import Site -from twisted.web.util import redirectTo - +from twisted.web.util import redirectTo + from bridgedb import captcha from bridgedb import crypto from bridgedb import strings @@ -49,8 +49,8 @@ from bridgedb import translations from bridgedb import txrecaptcha from bridgedb.Filters import filterBridgesByIP4 from bridgedb.Filters import filterBridgesByIP6 -from bridgedb.Filters import filterBridgesByTransport -from bridgedb.Filters import filterBridgesByNotBlockedIn +from bridgedb.Filters import filterBridgesByTransport +from bridgedb.Filters import filterBridgesByNotBlockedIn from bridgedb.https.request import HTTPSBridgeRequest from bridgedb.parse import headers from bridgedb.parse.addr import isIPAddress @@ -63,7 +63,7 @@ from bridgedb.util import replaceControlChars TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), 'templates') rtl_langs = ('ar', 'he', 'fa', 'gu_IN', 'ku') - + # Setting `filesystem_checks` to False is recommended for production servers, # due to potential speed increases. This means that the atimes of the Mako # template files aren't rechecked every time the template is requested @@ -214,10 +214,10 @@ class CaptchaProtectedResource(resource.Resource): resource.Resource.__init__(self) self.publicKey = publicKey self.secretKey = secretKey -self.useForwardedHeader = useForwardedHeader +self.useForwardedHeader = useForwardedHeader self.resource = protectedResource - -def getClientIP(self, request): + +def getClientIP(self, request): """Get the client's IP address from the :header:`X-Forwarded-For` header, or from the :api:`request `. @@ -228,7 +228,7 @@ class CaptchaProtectedResource(resource.Resource): :returns: The client's IP address, if it was obtainable. """ return getClientIP(request, self.useForwardedHeader) - + def getCaptchaImage(self, request=None): """Get a CAPTCHA image. @@ -269,7 +269,7 @@ class CaptchaProtectedResource(resource.Resource): """ return False -def render_GET(self, request): +def render_GET(self, request): """Retrieve a ReCaptcha from the API server and serve it to the client. :type request: :api:`twisted.web.http.Request` @@ -298,8 +298,8 @@ class CaptchaProtectedResource(resource.Resource): request.setHeader("Content-Type", "text/html; charset=utf-8") return rendered - -def render_POST(self, request): + +def render_POST(self, request): """Process a client's CAPTCHA solution. If the client's CAPTCHA solution is valid (according to @@ -328,8 +328,8 @@ class CaptchaProtectedResource(resource.Resource): logging.debug("Client failed a CAPTCHA; returning redirect to %s" % request.uri) return redirectTo(request.uri, request) - - + + class GimpCaptchaProtectedResource(CaptchaProtectedResource): """A web resource which uses a local cache of CAPTCHAs, generated with gimp-captcha_, to protect another resource. @@ -626,9 +626,9 @@ class ReCaptchaProtectedResource(CaptchaProtectedResource): class BridgesResource(resource.Resource): """This resource displays bridge lines in response to a request.""" -isLeaf = True - -def __init__(self, distributor, s
[tor-commits] [bridgedb/develop] Remove `countryCode` parameter from BridgeRing.getBridges().
commit 509fb2094d6cc02ba889bbc0a6883447e3131e7e Author: Isis Lovecruft Date: Thu Apr 16 04:14:52 2015 + Remove `countryCode` parameter from BridgeRing.getBridges(). It was never used. And it's unnecessary. --- lib/bridgedb/Bridges.py | 21 + 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py index 988d464..a13a73e 100644 --- a/lib/bridgedb/Bridges.py +++ b/lib/bridgedb/Bridges.py @@ -283,28 +283,17 @@ class BridgeRing(BridgeHolder): assert len(r) == N return r -def getBridges(self, pos, N=1, countryCode=None): +def getBridges(self, pos, N=1): """Return **N** bridges appearing in this hashring after a position. :param bytes pos: The position to jump to. Any bridges returned will - start at this position in the hashring, if there is - a bridge assigned to that position. Otherwise, - indexing will start at the first position after this - one which has a bridge assigned to it. +start at this position in the hashring, if there is a bridge +assigned to that position. Otherwise, indexing will start at the +first position after this one which has a bridge assigned to it. :param int N: The number of bridges to return. -:type countryCode: str or None -:param countryCode: DOCDOC :rtype: list -:returns: A list of :class:`~bridgedb.Bridges.Bridge`s. +:returns: A list of :class:`~bridgedb.bridges.Bridge`s. """ -# XXX This can be removed after we determine if countryCode is ever -# actually being used. It seems the countryCode should be passed in -# from bridgedb.https.server.WebResource.getBridgeRequestAnswer() in -# order to hand out bridges which are believed to not be blocked in a -# given country. -if countryCode: -logging.debug("getBridges: countryCode=%r" % countryCode) - forced = [] for _, _, count, subring in self.subrings: if len(subring) < count: ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Why were there ever unreachable subhashrings? Kill them with fire.
commit a45591af98741f5b4d7cf9a6cd5fbd1603c3bfe8 Author: Isis Lovecruft Date: Thu Apr 9 06:44:43 2015 + Why were there ever unreachable subhashrings? Kill them with fire. As part of #4297, $SOMEONE added the prepopulateRings() methods, which are used when BridgeDB parses incoming descriptors. These methods add subhashrings and allocate bridges to them. When a client requests bridges, they are either requesting IPv4 or IPv6 bridges, and thus clients *always* have either filterBridgesByIPv4 or filterBridgesByIPv6, respectively. So why is there an extra subhashring with no IP version filters if clients *can never get to it*? Blame $SOMEONE. The $SOMEONE who authored the commit below would be a good start. * BUGFIX on e6ce57e728802689544c130867edcadfeecd38ec. * REMOVE the "filterless" subhashring from the IPBasedDistributor. * UPDATE documentation for IPBasedDistributor.prepopulateRings(). --- lib/bridgedb/Dist.py | 34 +- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 954b570..0658504 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -233,33 +233,25 @@ class IPBasedDistributor(Distributor): | Subhashrings |||| ||| | (total, assigned)| (6,0) | (6,1) | (6,2) | (6,3) | (6,4) | (6,5) | +--+++++++ -| Filtered | (6,0) | (6,1) | (6,2) | (6,3) | (6,4) | (6,5) | -| Subhashrings +++++++ -| bBy requested| (6,0)-IPv4 | (6,1)-IPv4 | (6,2)-IPv4 | (6,3)-IPv4 | (6,4)-IPv4 | (6,5)-IPv4 | -| bridge type) +++++++ -| | (6,0)-IPv6 | (6,1)-IPv6 | (6,2)-IPv6 | (6,3)-IPv6 | (6,4)-IPv6 | (6,5)-IPv6 | +| Filtered | (6,0)-IPv4 | (6,1)-IPv4 | (6,2)-IPv4 | (6,3)-IPv4 | (6,4)-IPv4 | (6,5)-IPv4 | +| Subhashrings |||| ||| +| bBy requested +++++++ +| bridge type) | (6,0)-IPv6 | (6,1)-IPv6 | (6,2)-IPv6 | (6,3)-IPv6 | (6,4)-IPv6 | (6,5)-IPv6 | +| |||| ||| +--+++++++ -The "filtered subhashrings" are essentially copies of their respective -subhashring, that is, subhashring ``(6,0)`` contains both IPv4 and -IPv6 bridges, meaning that its contents are a superset of the filtered -subhashrings ``(6,0)-IPv4`` and ``(6,0)-IPv6``. (I have no idea of -the relation between ``(6,0)-IPv4`` and ``(6,0)-IPv6``, including -whether or not their contents are disjoint. I didn't design this shit, -I'm just redesigning it.) - -"Why does the ``(6,0)`` superset subhashring exist then?" +The "filtered subhashrings" are essentially filtered copies of their +respective subhashring, such that they only contain bridges which +support IPv4 or IPv6, respectively. (I have no idea of the relation +between ``(6,0)-IPv4`` and ``(6,0)-IPv6``, including whether or not +their contents are disjoint. I didn't design this shit, I'm just +redesigning it.) -you might ask. That's a very good question. I don't know either. -I'm inclined to think it shouldn't exist, unless we wish to allow -clients to request IPv4 bridges and IPv6 bridges simultaneously -(there's currently no interface to do this, however). - -Thus, in this example, we end up with **18 total subhashrings**. +Thus, in this example, we end up with **12 total subhashrings**. """ logging.info("Prepopulating %s distributor hashrings..." % self.name) # populate all rings (for dumping assignments and testing) -for filterFn in [None, filterBridgesByIP4, filterBridgesByIP6]: +for filterFn in [filterBridgesByIP4, filterBridgesByIP6]: n = self.nClusters for category in self.categories: g = filterAssignBridgesToRing(self.splitter.hmac, ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[bridgedb/develop] Rename ipCategories → proxySets.
commit 423f75d309abe304297cad2449e9a210347877da Author: Isis Lovecruft Date: Fri Apr 10 07:37:24 2015 + Rename ipCategories â proxySets. --- lib/bridgedb/Dist.py | 16 lib/bridgedb/test/test_HTTPServer.py |4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index f9f61de..2f63574 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -134,7 +134,7 @@ class IPBasedDistributor(Distributor): hashrings, one for each area in the ``areaMapper``. Every inserted bridge will go into one of these rings, and every area is associated with one. -:ivar categories: DOCDOC See :param:`ipCategories`. +:ivar categories: DOCDOC See :param:`proxySets`. :type splitter: :class:`bridgedb.Bridges.FixedBridgeSplitter` :ivar splitter: A hashring that assigns bridges to subrings with fixed proportions. Used to assign bridges into the subrings of this @@ -142,7 +142,7 @@ class IPBasedDistributor(Distributor): """ def __init__(self, areaMapper, numberOfClusters, key, - ipCategories=None, answerParameters=None): + proxySets=None, answerParameters=None): """Create a Distributor that decides which bridges to distribute based upon the client's IP address and the current time. @@ -160,8 +160,8 @@ class IPBasedDistributor(Distributor): :param bytes key: The master HMAC key for this distributor. All added bridges are HMACed with this key in order to place them into the hashrings. -:type ipCategories: iterable or None -:param ipCategories: DOCDOC +:type proxySets: iterable or None +:param proxySets: DOCDOC :type answerParameters: :class:`bridgedb.Bridges.BridgeRingParameters` :param answerParameters: A mechanism for ensuring that the set of bridges that this distributor answers a client with fit certain @@ -172,14 +172,14 @@ class IPBasedDistributor(Distributor): self.numberOfClusters = numberOfClusters self.answerParameters = answerParameters -if not ipCategories: -ipCategories = [] +if not proxySets: +proxySets = [] if not answerParameters: answerParameters = [] self.rings = [] self.categories = [] -for c in ipCategories: +for c in proxySets: self.categories.append(c) key2 = getHMAC(key, "Assign-Bridges-To-Rings") @@ -193,7 +193,7 @@ class IPBasedDistributor(Distributor): # # XXX Why is the "extra room" hardcoded to be 5? Shouldn't it be some # fraction of the number of clusters/categories? --isis -ring_cache_size = self.numberOfClusters + len(ipCategories) + 5 +ring_cache_size = self.numberOfClusters + len(proxySets) + 5 self.splitter = bridgedb.Bridges.FilteredBridgeSplitter( key2, max_cached_rings=ring_cache_size) logging.debug("Added splitter %s to IPBasedDistributor." diff --git a/lib/bridgedb/test/test_HTTPServer.py b/lib/bridgedb/test/test_HTTPServer.py index c3cf79a..103976e 100644 --- a/lib/bridgedb/test/test_HTTPServer.py +++ b/lib/bridgedb/test/test_HTTPServer.py @@ -488,7 +488,7 @@ class DummyIPBasedDistributor(object): def _dumbAreaMapper(ip): return ip def __init__(self, areaMapper=None, numberOfClusters=None, key=None, - ipCategories=None, answerParameters=None): + proxySets=None, answerParameters=None): """None of the parameters are really used, they are just there to retain an identical method signature. """ @@ -496,7 +496,7 @@ class DummyIPBasedDistributor(object): self.numberOfClusters = 3 self.nBridgesToGive = 3 self.key = self.__class__.__name__ -self.ipCategories = ipCategories +self.proxySets = proxySets self.answerParameters = answerParameters def getBridges(self, bridgeRequest=None, epoch=None, N=1): ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Remove IPBasedDistributor.clear() and EmailBasedDistributor.clear().
commit de631604e282c92bc3f54e56cfa0faa3416503b4 Author: Isis Lovecruft Date: Fri Apr 10 07:14:12 2015 + Remove IPBasedDistributor.clear() and EmailBasedDistributor.clear(). These were never used anywhere. --- lib/bridgedb/Dist.py |7 --- 1 file changed, 7 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 127004a..770198a 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -268,9 +268,6 @@ class IPBasedDistributor(Distributor): filterBridgesByRules(filters), populate_from=self.splitter.bridges) -def clear(self): -self.splitter.clear() - def insert(self, bridge): """Assign a bridge to this distributor.""" self.splitter.insert(bridge) @@ -410,10 +407,6 @@ class EmailBasedDistributor(Distributor): self.setDistributorName('Email') -def clear(self): -self.splitter.clear() -#self.ring.clear() # should be take care of by above - def insert(self, bridge): """Assign a bridge to this distributor.""" self.splitter.insert(bridge) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Generalise BridgeRequestBase.isValid().
commit 7ebd8914e30fea061ecf6b537bb186660946db18 Author: Isis Lovecruft Date: Thu Apr 2 05:00:56 2015 + Generalise BridgeRequestBase.isValid(). It's now suitable for inheritance by email.request and https.request, so we can remove the custom methods from both. --- lib/bridgedb/bridgerequest.py | 17 + lib/bridgedb/email/request.py | 15 --- 2 files changed, 9 insertions(+), 23 deletions(-) diff --git a/lib/bridgedb/bridgerequest.py b/lib/bridgedb/bridgerequest.py index f653450..f7aa031 100644 --- a/lib/bridgedb/bridgerequest.py +++ b/lib/bridgedb/bridgerequest.py @@ -130,16 +130,17 @@ class BridgeRequestBase(object): return position def isValid(self, valid=None): -"""Set or determine if this request was valid. +"""Get or set the validity of this bridge request. -:type valid: None or bool -:param valid: If ``None``, get the current request validity. If -``True`` or ``False``, set the request validity accordingly. -:rtype: bool -:returns: Whether or not this request is valid. +If called without parameters, this method will return the current +state, otherwise (if called with the **valid** parameter), it will set +the current state of validity for this request. + +:param bool valid: If given, set the validity state of this +request. Otherwise, get the current state. """ -if isinstance(valid, bool): -self.valid = valid +if valid is not None: +self.valid = bool(valid) return self.valid def withIPv4(self): diff --git a/lib/bridgedb/email/request.py b/lib/bridgedb/email/request.py index 9c0f0c2..32446ac 100644 --- a/lib/bridgedb/email/request.py +++ b/lib/bridgedb/email/request.py @@ -108,23 +108,8 @@ class EmailBridgeRequest(bridgerequest.BridgeRequestBase): :class:`~bridgedb.Dist.EmailBasedDistributor`. """ super(EmailBridgeRequest, self).__init__() -self._isValid = False self._wantsKey = False -def isValid(self, valid=None): -"""Get or set the validity of this bridge request. - -If called without parameters, this method will return the current -state, otherwise (if called with the **valid** parameter), it will set -the current state of validity for this request. - -:param bool valid: If given, set the validity state of this -request. Otherwise, get the current state. -""" -if valid is not None: -self._isValid = bool(valid) -return self._isValid - def wantsKey(self, wantsKey=None): """Get or set whether this bridge request wanted our GnuPG key. ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Refactor getBridgesForIP() to use b.https.request.HTTPSBridgeRequest.
commit 7b880a1fe0f346c85364b255eee93995a6b31b94 Author: Isis Lovecruft Date: Wed Apr 1 08:40:50 2015 + Refactor getBridgesForIP() to use b.https.request.HTTPSBridgeRequest. * RENAME b.D.IPBasedDistributor.getBridgesForIP() â b.D.IPBasedDistributor.getBridges(). * CREATE new bridgedb.https package. * CREATE new bridgedb.https.request module. * CHANGE b.D.IPBasedDistributor.getBridges() to use bridgedb.https.request.HTTPSBridgeRequest. --- doc/sphinx/source/bridgedb.https.rst | 10 +++ doc/sphinx/source/bridgedb.rst |1 + lib/bridgedb/Dist.py | 143 ++ lib/bridgedb/HTTPServer.py | 142 ++--- lib/bridgedb/https/__init__.py |1 + lib/bridgedb/https/request.py| 143 ++ lib/bridgedb/test/legacy_Tests.py| 26 +++ lib/bridgedb/test/test_HTTPServer.py | 27 --- setup.py |1 + 9 files changed, 301 insertions(+), 193 deletions(-) diff --git a/doc/sphinx/source/bridgedb.https.rst b/doc/sphinx/source/bridgedb.https.rst new file mode 100644 index 000..b0ee95c --- /dev/null +++ b/doc/sphinx/source/bridgedb.https.rst @@ -0,0 +1,10 @@ +.. _https-pkg: + +bridgedb.https +--- + +.. contents:: bridgedb.https +:depth: 3 + +.. automodule:: bridgedb.https.__init__ +.. automodule:: bridgedb.https.request diff --git a/doc/sphinx/source/bridgedb.rst b/doc/sphinx/source/bridgedb.rst index 3f87647..61ab07f 100644 --- a/doc/sphinx/source/bridgedb.rst +++ b/doc/sphinx/source/bridgedb.rst @@ -17,6 +17,7 @@ BridgeDB Package and Module Documentation bridgedb.email bridgedb.Filters bridgedb.geo +bridgedb.https bridgedb.HTTPServer bridgedb.interfaces bridgedb.Main diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 26e952e..3f7835b 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -305,118 +305,92 @@ class IPBasedDistributor(Distributor): """Assign a bridge to this distributor.""" self.splitter.insert(bridge) -def getBridgesForIP(self, ip, epoch, N=1, countryCode=None, -bridgeFilterRules=None): +def _buildHashringFilters(self, previousFilters, clientCluster): +totalRings = self.nClusters + len(self.categories) +g = filterAssignBridgesToRing(self.splitter.hmac, totalRings, clientCluster) +previousFilters.append(g) +return frozenset(previousFilters) + +def getBridges(self, bridgeRequest, interval, N=1): """Return a list of bridges to give to a user. -:param str ip: The user's IP address, as a dotted quad. -:param str epoch: The time period when we got this request. This can - be any string, so long as it changes with every - period. +:type bridgeRequest: :class:`bridgedb.https.request.HTTPSBridgeRequest` +:param bridgeRequest: A :class:`~bridgedb.bridgerequest.BridgeRequestBase` +with the :data:`~bridgedb.bridgerequest.BridgeRequestBase.client` +attribute set to a string containing the client's IP address. +:param str interval: The time period when we got this request. This +can be any string, so long as it changes with every period. :param int N: The number of bridges to try to give back. (default: 1) -:param str countryCode: The two-letter geoip country code of the -client's IP address. If given, it is assumed that any bridges -distributed to that client should not be blocked in that -country. (default: None) -:param list bridgeFilterRules: A list of callables used filter the - bridges returned in the response to the - client. See :mod:`~bridgedb.Filters`. :rtype: list :return: A list of :class:`~bridgedb.Bridges.Bridge`s to include in - the response. See - :meth:`bridgedb.HTTPServer.WebResource.getBridgeRequestAnswer` - for an example of how this is used. +the response. See + :meth:`bridgedb.HTTPServer.WebResourceBridges.getBridgeRequestAnswer` +for an example of how this is used. """ logging.info("Attempting to return %d bridges to client %s..." - % (N, ip)) - -if not bridgeFilterRules: -bridgeFilterRules=[] + % (N, bridgeRequest.client)) if not len(self.splitter): logging.warn("Bailing! Splitter has zero bridges!") return [] -logging.debug("Bridges in splitter:\t%d" % len(self.splitter)) -logging.debug("Client request epoch:\t%s" % epoch) -logging.debug("Active bridge filters:\t%s" - % ' '.joi
[tor-commits] [bridgedb/develop] Remove the idea of "categories". Proxies constitute another cluster.
commit 9ba68b455a8adeaef34785ecccbe7ac5a5d5ac26 Author: Isis Lovecruft Date: Sat Apr 11 01:10:05 2015 + Remove the idea of "categories". Proxies constitute another cluster. This completely removes the half-baked idea of "IP categories" from BridgeDB's codebase. An IPBasedDistributor now holds a bunch of proxies (in one single bridgedb.proxy.ProxySet). These proxies have their own "cluster". End of story. No more messing around with both "categories" and "clusters", because nobody ever knew what either of those were anyway, much less why they were different. * CHANGE IPBasedDistributor.categories to be a single bridgedb.proxy.ProxySet, rather than a list of lists. ProxySets have "tags" for each proxy within them, and can efficiently separate proxies based upon tag(s), so there is no longer any need to have a list of lists to keep the proxies separate. Besides, in the end, we treat all clients coming from any proxy the same, regardless of whether the proxy is a Tor Exit relay or some other known open proxy. * RENAME IPBasedDistributor.categories â IPBasedDistributor.proxies, because no one ever understood what an "IP category" was. * CHANGE IPBasedDistributor.numberOfClusters to always include the "cluster" for clients coming from proxies, if IPBasedDistributor.proxies is configured. * ADD IPBasedDistributor.proxyCluster, which is an integer pointing to the cluster number for the proxies cluster. If there is no cluster for proxies, it is set to 0. Otherwise, it points to the last cluster. * CHANGE the numbering of clusters in IPBasedDistributor to start from 1 instead of 0. While this might make iteration over all of the clusters increasingly subject to fencepost errors, it still makes the code feel more intuitive, i.e. "The first cluster is 1 out of 5 total clusters, and the last cluster is 5/5" rather than "The first cluster is number 0 out of 5 total clusters, and the last 4/5". * CHANGE a couple test cases which expected IPBasedDistributor.categories to exist. * UPDATE documentation pertaining to all of the above, as well as the documentation on (sub)hashring structure. --- lib/bridgedb/Dist.py | 172 +++-- lib/bridgedb/Main.py | 41 +++-- lib/bridgedb/test/legacy_Tests.py | 11 ++- lib/bridgedb/test/test_Main.py|4 +- 4 files changed, 107 insertions(+), 121 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 2f63574..ab7ae6e 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -20,6 +20,7 @@ import time import bridgedb.Bridges import bridgedb.Storage +from bridgedb import proxy from bridgedb.crypto import getHMAC from bridgedb.crypto import getHMACFunc from bridgedb.Filters import filterAssignBridgesToRing @@ -134,7 +135,9 @@ class IPBasedDistributor(Distributor): hashrings, one for each area in the ``areaMapper``. Every inserted bridge will go into one of these rings, and every area is associated with one. -:ivar categories: DOCDOC See :param:`proxySets`. +:type proxies: :class:`~bridgedb.proxies.ProxySet` +:ivar proxies: All known proxies, which we treat differently. See +:param:`proxies`. :type splitter: :class:`bridgedb.Bridges.FixedBridgeSplitter` :ivar splitter: A hashring that assigns bridges to subrings with fixed proportions. Used to assign bridges into the subrings of this @@ -142,7 +145,7 @@ class IPBasedDistributor(Distributor): """ def __init__(self, areaMapper, numberOfClusters, key, - proxySets=None, answerParameters=None): + proxies=None, answerParameters=None): """Create a Distributor that decides which bridges to distribute based upon the client's IP address and the current time. @@ -160,27 +163,33 @@ class IPBasedDistributor(Distributor): :param bytes key: The master HMAC key for this distributor. All added bridges are HMACed with this key in order to place them into the hashrings. -:type proxySets: iterable or None -:param proxySets: DOCDOC +:type proxies: :class:`~bridgedb.proxy.ProxySet` +:param proxies: A :class:`bridgedb.proxy.ProxySet` containing known +Tor Exit relays and other known proxies. These will constitute +the extra cluster, and any client requesting bridges from one of +these **proxies** will be distributed bridges from a separate +subhashring that is specific to Tor/proxy users. :type answerParameters: :class:`bridgedb.Bridges.BridgeRingParameters` :param answerParameters: A mechanism for ensuring that the set of bridges that th
[bridgedb/develop] Rename nCluster → numberOfClusters.
commit d85f4f710ebd67a32f43ea3db0426a9a7e67036b Author: Isis Lovecruft Date: Fri Apr 10 07:34:44 2015 + Rename nCluster â numberOfClusters. --- lib/bridgedb/Dist.py | 24 lib/bridgedb/test/test_HTTPServer.py |4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 770198a..f9f61de 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -141,7 +141,7 @@ class IPBasedDistributor(Distributor): distributor. """ -def __init__(self, areaMapper, nClusters, key, +def __init__(self, areaMapper, numberOfClusters, key, ipCategories=None, answerParameters=None): """Create a Distributor that decides which bridges to distribute based upon the client's IP address and the current time. @@ -151,9 +151,9 @@ class IPBasedDistributor(Distributor): strings, such that addresses which map to identical strings are considered to be in the same "area" (for some arbitrary definition of "area"). See :func:`bridgedb.Dist.uniformMap` for an example. -:param integer nClusters: The number of clusters to group IP addresses +:param integer numberOfClusters: The number of clusters to group IP addresses into. Note that if PROXY_LIST_FILES is set in bridgedb.conf, then -the actual number of clusters is one higher than ``nClusters``, +the actual number of clusters is one higher than ``numberOfClusters``, because the set of known open proxies constitutes its own category. DOCDOC What exactly does a cluster *do*? @@ -169,7 +169,7 @@ class IPBasedDistributor(Distributor): bridges" or "at least one bridge on port 443", etc. """ self.areaMapper = areaMapper -self.nClusters = nClusters +self.numberOfClusters = numberOfClusters self.answerParameters = answerParameters if not ipCategories: @@ -193,7 +193,7 @@ class IPBasedDistributor(Distributor): # # XXX Why is the "extra room" hardcoded to be 5? Shouldn't it be some # fraction of the number of clusters/categories? --isis -ring_cache_size = self.nClusters + len(ipCategories) + 5 +ring_cache_size = self.numberOfClusters + len(ipCategories) + 5 self.splitter = bridgedb.Bridges.FilteredBridgeSplitter( key2, max_cached_rings=ring_cache_size) logging.debug("Added splitter %s to IPBasedDistributor." @@ -207,13 +207,13 @@ class IPBasedDistributor(Distributor): The hashring structure for this distributor is influenced by the ``N_IP_CLUSTERS`` configuration option, as well as the number of -``PROXY_LIST_FILES``. Essentially, :data:`nClusters` is set to the +``PROXY_LIST_FILES``. Essentially, :data:`numberOfClusters` is set to the specified ``N_IP_CLUSTERS``. The ``PROXY_LIST_FILES`` (plus the :class:`bridgedb.proxy.ProxySet` for the Tor Exit list downloaded into memory with :script:`get-tor-exits`) are stored in :data:`categories`. The number of subhashrings which this :class:`Distributor` has active -in its hashring is then the :data:`nClusters` plus the number of +in its hashring is then the :data:`numberOfClusters` plus the number of :data:`categories`. As an example, if BridgeDB was configured with ``N_IP_CLUSTERS=4`` and @@ -255,14 +255,14 @@ class IPBasedDistributor(Distributor): # XXX Distributors should have a "totalClusters" property in order # to avoid reusing this unclear construct all over the place. (Or # just get rid of the idea of "categories".) -for cluster in range(self.nClusters + len(self.categories)): +for cluster in range(self.numberOfClusters + len(self.categories)): filters = self._buildHashringFilters([filterFn,], cluster) key1 = getHMAC(self.splitter.key, "Order-Bridges-In-Ring-%d" % cluster) ring = bridgedb.Bridges.BridgeRing(key1, self.answerParameters) # For consistency with previous implementation of this method, # only set the "name" for "clusters" which are in this # distributor's categories: -if cluster >= self.nClusters: +if cluster >= self.numberOfClusters: ring.setName('{0} Ring'.format(self.name)) self.splitter.addRing(ring, filters, filterBridgesByRules(filters), @@ -273,7 +273,7 @@ class IPBasedDistributor(Distributor): self.splitter.insert(bridge) def _buildHashringFilters(self, previousFilters, clientCluster): -totalRings = self.nClusters + len(self.categories) +totalRings = self.numberOf
[tor-commits] [bridgedb/develop] Deduplicate subhashring logic in IPBasedDistributor.prepopulateRings().
commit 023596e567e17fd801a7cbc4827b4836908c73fe Author: Isis Lovecruft Date: Thu Apr 9 23:27:36 2015 + Deduplicate subhashring logic in IPBasedDistributor.prepopulateRings(). --- lib/bridgedb/Dist.py | 51 ++ 1 file changed, 14 insertions(+), 37 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 0658504..127004a 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -250,45 +250,22 @@ class IPBasedDistributor(Distributor): Thus, in this example, we end up with **12 total subhashrings**. """ logging.info("Prepopulating %s distributor hashrings..." % self.name) -# populate all rings (for dumping assignments and testing) -for filterFn in [filterBridgesByIP4, filterBridgesByIP6]: -n = self.nClusters -for category in self.categories: -g = filterAssignBridgesToRing(self.splitter.hmac, - self.nClusters + - len(self.categories), - n) -bridgeFilterRules = [g] -if filterFn: -bridgeFilterRules.append(filterFn) -ruleset = frozenset(bridgeFilterRules) -key1 = getHMAC(self.splitter.key, - "Order-Bridges-In-Ring-%d" % n) -n += 1 -ring = bridgedb.Bridges.BridgeRing(key1, self.answerParameters) -ring.setName('{0} Ring'.format(self.name)) -self.splitter.addRing(ring, - ruleset, - filterBridgesByRules(bridgeFilterRules), - populate_from=self.splitter.bridges) - -# populate all ip clusters -for clusterNum in xrange(self.nClusters): -g = filterAssignBridgesToRing(self.splitter.hmac, - self.nClusters + - len(self.categories), - clusterNum) -bridgeFilterRules = [g] -if filterFn: -bridgeFilterRules.append(filterFn) -ruleset = frozenset(bridgeFilterRules) -key1 = getHMAC(self.splitter.key, - "Order-Bridges-In-Ring-%d" % clusterNum) +for filterFn in [filterBridgesByIP4, filterBridgesByIP6]: +# XXX Distributors should have a "totalClusters" property in order +# to avoid reusing this unclear construct all over the place. (Or +# just get rid of the idea of "categories".) +for cluster in range(self.nClusters + len(self.categories)): +filters = self._buildHashringFilters([filterFn,], cluster) +key1 = getHMAC(self.splitter.key, "Order-Bridges-In-Ring-%d" % cluster) ring = bridgedb.Bridges.BridgeRing(key1, self.answerParameters) -self.splitter.addRing(ring, - ruleset, - filterBridgesByRules(bridgeFilterRules), +# For consistency with previous implementation of this method, +# only set the "name" for "clusters" which are in this +# distributor's categories: +if cluster >= self.nClusters: +ring.setName('{0} Ring'.format(self.name)) +self.splitter.addRing(ring, filters, + filterBridgesByRules(filters), populate_from=self.splitter.bridges) def clear(self): ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Separate BridgeHolder class from Distributor.
commit de555a5908d18cbb04c34afa88a7138ab204753f Author: Isis Lovecruft Date: Thu Apr 9 06:35:27 2015 + Separate BridgeHolder class from Distributor. * FIXES part of #12506: https://bugs.torproject.org/12506 --- lib/bridgedb/Bridges.py|1 - lib/bridgedb/Dist.py |3 ++- lib/bridgedb/test/test_Main.py |7 +-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/bridgedb/Bridges.py b/lib/bridgedb/Bridges.py index d9b28e2..c727c9a 100644 --- a/lib/bridgedb/Bridges.py +++ b/lib/bridgedb/Bridges.py @@ -449,7 +449,6 @@ class BridgeSplitter(BridgeHolder): p -- the relative proportion of bridges to assign to this bridgeholder. """ -assert isinstance(ring, BridgeHolder) self.ringsByName[ringname] = ring self.pValues.append(self.totalP) self.rings.append(ringname) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 69d9eb6..954b570 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -92,7 +92,8 @@ def getNumBridgesPerAnswer(ring, max_bridges_per_answer=3): return n_bridges_per_answer -class Distributor(bridgedb.Bridges.BridgeHolder): + +class Distributor(object): """Distributes bridges to clients.""" def __init__(self): diff --git a/lib/bridgedb/test/test_Main.py b/lib/bridgedb/test/test_Main.py index 5ae4025..9c8b68c 100644 --- a/lib/bridgedb/test/test_Main.py +++ b/lib/bridgedb/test/test_Main.py @@ -27,7 +27,6 @@ from twisted.internet.threads import deferToThread from twisted.trial import unittest from bridgedb import Main -from bridgedb.Bridges import BridgeHolder from bridgedb.parse.options import parseOptions @@ -59,13 +58,17 @@ def mockUpdateBridgeHistory(bridges, timestamps): (fingerprint, timestamp)) -class MockBridgeHolder(BridgeHolder): +class MockBridgeHolder(object): def __init__(self): self._bridges = {} def __len__(self): return len(self._bridges.keys()) def insert(self, bridge): self._bridges[bridge.fingerprint] = bridge +def clear(self): +pass +def dumpAssignments(self): +pass class MainTests(unittest.TestCase): ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Deduplicate getClientIP() function in bridgedb.HTTPServer.
commit 06c22e1b40bec96502331fd7054c2354ef1eea38 Author: Isis Lovecruft Date: Wed Apr 1 08:38:53 2015 + Deduplicate getClientIP() function in bridgedb.HTTPServer. --- lib/bridgedb/HTTPServer.py | 53 ++-- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/lib/bridgedb/HTTPServer.py b/lib/bridgedb/HTTPServer.py index beff4bd..8c58380 100644 --- a/lib/bridgedb/HTTPServer.py +++ b/lib/bridgedb/HTTPServer.py @@ -75,6 +75,33 @@ lookup = TemplateLookup(directories=[TEMPLATE_DIR], collection_size=500) logging.debug("Set template root to %s" % TEMPLATE_DIR) + +def getClientIP(request, useForwardedHeader=False): +"""Get the client's IP address from the :header:`X-Forwarded-For` +header, or from the :api:`request `. + +:type request: :api:`twisted.web.http.Request` +:param request: A ``Request`` object for a +:api:`twisted.web.resource.Resource`. +:param bool useForwardedHeader: If ``True``, attempt to get the client's +IP address from the :header:`X-Forwarded-For` header. +:rtype: None or str +:returns: The client's IP address, if it was obtainable. +""" +ip = None + +if useForwardedHeader: +header = request.getHeader("X-Forwarded-For") +if header: +ip = header.split(",")[-1].strip() +if not isIPAddress(ip): +logging.warn("Got weird X-Forwarded-For value %r" % header) +ip = None +else: +ip = request.getClientIP() + +return ip + def replaceErrorPage(error, template_name=None): """Create a general error page for displaying in place of tracebacks. @@ -138,20 +165,13 @@ class CaptchaProtectedResource(resource.Resource): """Get the client's IP address from the :header:`X-Forwarded-For` header, or from the :api:`request `. +:type request: :api:`twisted.web.http.Request` +:param request: A ``Request`` object for a +:api:`twisted.web.resource.Resource`. :rtype: None or str :returns: The client's IP address, if it was obtainable. """ -ip = None -if self.useForwardedHeader: -h = request.getHeader("X-Forwarded-For") -if h: -ip = h.split(",")[-1].strip() -if not isIPAddress(ip): -logging.warn("Got weird X-Forwarded-For value %r" % h) -ip = None -else: -ip = request.getClientIP() -return ip +return getClientIP(request, self.useForwardedHeader) def getCaptchaImage(self, request=None): """Get a CAPTCHA image. @@ -667,16 +687,7 @@ class WebResourceBridges(resource.Resource): ip = None countryCode = None -# XXX this code is duplicated in CaptchaProtectedResource -if self.useForwardedHeader: -h = request.getHeader("X-Forwarded-For") -if h: -ip = h.split(",")[-1].strip() -if not isIPAddress(ip): -logging.warn("Got weird forwarded-for value %r",h) -ip = None -else: -ip = request.getClientIP() +ip = getClientIP(request, self.useForwardedForHeader) # Look up the country code of the input IP if isIPAddress(ip): ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[bridgedb/develop] Rename in EmailBasedDistributor.getBridges() `epoch` → `interval`.
commit 53732c492d29f094d17530bf60d740d957b21eab Author: Isis Lovecruft Date: Thu Apr 9 05:03:37 2015 + Rename in EmailBasedDistributor.getBridges() `epoch` â `interval`. --- lib/bridgedb/Dist.py |6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 3f7835b..69d9eb6 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -448,7 +448,7 @@ class EmailBasedDistributor(Distributor): """Assign a bridge to this distributor.""" self.splitter.insert(bridge) -def getBridges(self, bridgeRequest, epoch, N=1): +def getBridges(self, bridgeRequest, interval, N=1): """Return a list of bridges to give to a user. :type bridgeRequest: :class:`~bridgedb.email.request.EmailBridgeRequest` @@ -456,7 +456,7 @@ class EmailBasedDistributor(Distributor): with the :data:`~bridgedb.bridgerequest.BridgeRequestBase.client` attribute set to a string containing the client's full, canonicalized email address. -:param epoch: The time period when we got this request. This can be +:param interval: The time period when we got this request. This can be any string, so long as it changes with every period. :param int N: The number of bridges to try to give back. """ @@ -501,7 +501,7 @@ class EmailBasedDistributor(Distributor): elif wasWarned: db.setWarnedEmail(bridgeRequest.client, False) -pos = self.emailHmac("<%s>%s" % (epoch, bridgeRequest.client)) +pos = self.emailHmac("<%s>%s" % (interval, bridgeRequest.client)) ring = None ruleset = frozenset(bridgeRequest.filters) ___ tor-commits mailing list tor-commits@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits
[tor-commits] [bridgedb/develop] Refactor getBridgesForEmail() to use EmailBridgeRequests.
commit 7c339c18cd3f190521369d5047bbd7ccf369 Author: Isis Lovecruft Date: Wed Apr 1 05:54:53 2015 + Refactor getBridgesForEmail() to use EmailBridgeRequests. * RENAME b.D.EmailBasedDistributor.getBridgesForEmail() â b.D.EmailBasedDistributor.getBridges(). * CHANGE b.D.EmailBasedDistributor.getBridges() to use bridgedb.email.request.EmailBridgeRequest. --- lib/bridgedb/Dist.py| 60 --- lib/bridgedb/email/autoresponder.py | 16 -- lib/bridgedb/test/email_helpers.py | 24 +++--- lib/bridgedb/test/legacy_Tests.py |6 ++-- 4 files changed, 48 insertions(+), 58 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 39e70be..26e952e 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -473,65 +473,63 @@ class EmailBasedDistributor(Distributor): """Assign a bridge to this distributor.""" self.splitter.insert(bridge) -def getBridgesForEmail(self, emailaddress, epoch, N=1, parameters=None, - countryCode=None, bridgeFilterRules=None): +def getBridges(self, bridgeRequest, epoch, N=1): """Return a list of bridges to give to a user. -:param str emailaddress: The user's email address, as given in a -:header:`From:` line. +:type bridgeRequest: :class:`~bridgedb.email.request.EmailBridgeRequest` +:param bridgeRequest: A :class:`~bridgedb.bridgerequest.BridgeRequestBase` +with the :data:`~bridgedb.bridgerequest.BridgeRequestBase.client` +attribute set to a string containing the client's full, canonicalized +email address. :param epoch: The time period when we got this request. This can be any string, so long as it changes with every period. :param int N: The number of bridges to try to give back. -:param parameters: DOCDOC -:param countryCode: DOCDOC -:param bridgeFilterRules: DOCDOC """ -if not bridgeFilterRules: -bridgeFilterRules=[] -now = time.time() - # All checks on the email address, such as checks for whitelisting and # canonicalization of domain name, are done in # :meth:`bridgedb.email.autoresponder.getMailTo` and # :meth:`bridgedb.email.autoresponder.SMTPAutoresponder.runChecks`. -if not emailaddress: -logging.error(("%s distributor can't get bridges for blank email " - "address!") % (self.name, emailaddress)) -return [] +if (not bridgeRequest.client) or (bridgeRequest.client == 'default'): +raise addr.BadEmail( +("%s distributor can't get bridges for invalid email email " + " address: %s") % (self.name, bridgeRequest.client)) + +now = time.time() with bridgedb.Storage.getDB() as db: -wasWarned = db.getWarnedEmail(emailaddress) -lastSaw = db.getEmailTime(emailaddress) +wasWarned = db.getWarnedEmail(bridgeRequest.client) +lastSaw = db.getEmailTime(bridgeRequest.client) logging.info("Attempting to return for %d bridges for %s..." - % (N, emailaddress)) + % (N, bridgeRequest.client)) if lastSaw is not None: -if emailaddress in self.whitelist.keys(): +if bridgeRequest.client in self.whitelist.keys(): logging.info(("Whitelisted email address %s was last seen " "%d seconds ago.") - % (emailaddress, now - lastSaw)) + % (bridgeRequest.client, now - lastSaw)) elif (lastSaw + MAX_EMAIL_RATE) >= now: wait = (lastSaw + MAX_EMAIL_RATE) - now logging.info("Client %s must wait another %d seconds." - % (emailaddress, wait)) + % (bridgeRequest.client, wait)) if wasWarned: -raise IgnoreEmail("Client was warned.", emailaddress) +raise IgnoreEmail("Client was warned.", + bridgeRequest.client) else: logging.info("Sending duplicate request warning.") -db.setWarnedEmail(emailaddress, True, now) +db.setWarnedEmail(bridgeRequest.client, True, now) db.commit() raise TooSoonEmail("Must wait %d seconds" % wait, - emailaddress) + bridgeRequest.client) # warning period is over elif wasWarned: -db.setWarnedEmail(emailaddress, F