[tor-commits] [translation-tools/master] Drop tor messenger strings

2018-05-08 Thread colin
commit 50f551fe1901196eb098de81573c6999766d0a61
Author: Colin Childs 
Date:   Wed May 9 00:11:37 2018 -0500

Drop tor messenger strings
---
 config | 8 
 1 file changed, 8 deletions(-)

diff --git a/config b/config
index 5bfae8c..d88a335 100644
--- a/config
+++ b/config
@@ -26,14 +26,6 @@ torbutton-aboutdialogdtd_completed 
torbutton-abouttorproperties
 torbutton-abouttorproperties_completed tails-openpgp-applet
 tails-openpgp-applet_completed torbutton-abouttbupdatedtd
 torbutton-abouttbupdatedtd_completed tails-onioncircuits 
tails-onioncircuits_completed
-tor-messenger-authdtd tor-messenger-authdtd_completed
-tor-messenger-authproperties_completed tor-messenger-authproperties
-tor-messenger-fingerdtd tor-messenger-fingerdtd_completed
-tor-messenger-otrproperties tor-messenger-otrproperties_completed
-tor-messenger-prefsdtd tor-messenger-prefsdtd_completed
-tor-messenger-privdtd tor-messenger-privdtd_completed
-tor-messenger-privproperties tor-messenger-privproperties_completed
-tor-messenger-uiproperties tor-messenger-uiproperties_completed
 tails-greeter-2 tails-greeter-2_completed exoneratorproperties
 exoneratorproperties_completed tor-browser-manual
 tor-browser-manual_completed support-censorship support-censorship_completed

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Fix compilation of test_addr.c

2018-05-08 Thread nickm
commit 01d729cbfe88e8a77b7bd42434e32771402f3fe7
Author: Nick Mathewson 
Date:   Tue May 8 20:20:54 2018 -0400

Fix compilation of test_addr.c

This needs to include crypto_rand.h (which it didn't before it was
merged).
---
 src/test/test_addr.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/test/test_addr.c b/src/test/test_addr.c
index 505e1533d..40db31320 100644
--- a/src/test/test_addr.c
+++ b/src/test/test_addr.c
@@ -6,6 +6,7 @@
 #define ADDRESSMAP_PRIVATE
 #include "orconfig.h"
 #include "or.h"
+#include "crypto_rand.h"
 #include "test.h"
 #include "addressmap.h"
 #include "log_test_helpers.h"

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/support-tbb] Update translations for support-tbb

2018-05-08 Thread translation
commit e6451b3ff8148b34ea157a78977e9b5a9fa3671f
Author: Translation commit bot 
Date:   Wed May 9 00:20:31 2018 +

Update translations for support-tbb
---
 nb.json | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/nb.json b/nb.json
index 3908f8f67..05350dc5a 100644
--- a/nb.json
+++ b/nb.json
@@ -134,19 +134,19 @@
 "tbb-22": {
"id": "#tbb-22",
"control": "tbb-22",
-   "title": "How can I make Tor run faster? Is Tor Browser slower than 
other browsers?",
+   "title": "Hvordan kan jeg få Tor til å kjøre raskere? Er 
Tor-nettleseren tregere enn andre nettlesere?",
"description": "Using Tor Browser can sometimes be 
slower than other browsers. The Tor network has over a million daily users, and 
just over 6000 relays to route all of their traffic, and the load on each 
server can sometimes cause latency. You can help improve the speed of the 
network by running your own relay, or encouraging others to do so. That said, 
Tor is much faster than it used to be and you may not actually notice any 
change in speed from other browsers."
 },
 "tbb-23": {
"id": "#tbb-23",
"control": "tbb-23",
-   "title": "What search engine comes with Tor Browser and how does it 
protect my privacy?",
-   "description": "DuckDuckGo is the default search 
engine in Tor Browser. DuckDuckGo does not track its users nor does it store 
any data about user searches."
+   "title": "Hvilken søkemotor kommer med Tor-nettleseren, og hvordan tar 
den hensyn til mitt personvern?",
+   "description": "DuckDuckGo er forvalgt søkemotor i 
Tor-nettleseren. DuckDuckGo sporer ikke sine brukere, og lagrer ikke data om 
brukersøk."
 },
 "tbb-24": {
"id": "#tbb-24",
"control": "tbb-24",
-   "title": "I'm having a problem with DuckDuckGo.",
+   "title": "Jeg har et problem med DuckDuckGo.",
"description": "Please see the ​https://duck.co/help\;>DuckDuckGo support portal. If you 
believe this is a Tor Browser issue, please report it on our ​https://trac.torproject.org/\;>bug tracker."
 },
 "tbb-25": {
@@ -164,7 +164,7 @@
 "tbb-27": {
"id": "#tbb-27",
"control": "tbb-27",
-   "title": "How do I update Tor Browser?",
+   "title": "Hvordan oppdaterer jeg Tor-nettleseren?",
"description": "You can update Tor Browser as soon as 
a new version is released.Tor Browser will 
prompt you to update the software once a new version has been released.The Torbutton icon (the little green onion in the top left 
corner of the browser) will display a yellow triangle.You may see a written indication when Tor Browser opens telling 
you that an update is available.Card titleCard 
textTor browser will install the 
updates.Card titleCard 
text"
 },
 "tbb-28": {
@@ -176,25 +176,25 @@
 "tbb-29": {
"id": "#tbb-29",
"control": "tbb-29",
-   "title": "Is there a way to change the IP address that Tor Browser 
assigns me for a particular site?",
+   "title": "Finnes det noen måte å endre IP-adressen Tor-nettleseren 
tildeler meg for en gitt side?",
"description": "Tor Browser has two ways to change 
your relay circuit — \"New Identity\" and \"New Tor Circuit for this Site\". 
Both options are located in the Torbutton (little green onion) menu.New 
IdentityThis option is useful if you want to prevent 
your subsequent browser activity from being linkable to what you were doing 
before. Selecting it will close all your tabs and windows, clear all private 
information such as cookies and browsing history, and use new Tor circuits for 
all connections. Tor Browser will warn you that all activity and downloads will 
be stopped, so take this into account before clicking \"New 
Identity\".New Tor Circuit for this SiteThis 
option is useful if the exit relay you are using is unable to connect to the 
website you require, or is not loading it properly. Selecting it will cause the 
currently-active tab or window to be reloaded over a new Tor circuit. Other 
open tabs a
 nd windows from the same website will use the new circuit as well once they 
are reloaded. This option does not clear any private information or unlink your 
activity, nor does it affect your current connections to other 
websites.Card titleCard text"
 },
 "tbb-30": {
"id": "#tbb-30",
"control": "tbb-30",
-   "title": "A website (bank, email provider, etc..) locks me out whenever 
I use Tor, what can I do?",
+   "title": "En nettside (bank, e-posttilbyder, osv.) låser meg ute når 
jeg bruker Tor, hva kan jeg gjøre?",
"description": "Tor Browser often makes your 
connection appear as though it is coming from an entirely different part of the 
world. Some websites, such as banks or email providers, might interpret this as 
a sign that your account has been compromised, and lock you out. The only 

[tor-commits] [translation/support-faq] Update translations for support-faq

2018-05-08 Thread translation
commit 8705a9c859e4504ea75d99eba6fdee4e956fa7f0
Author: Translation commit bot 
Date:   Wed May 9 00:20:03 2018 +

Update translations for support-faq
---
 nb.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nb.json b/nb.json
index fa464d008..a17ae6973 100644
--- a/nb.json
+++ b/nb.json
@@ -20,7 +20,7 @@
 "faq-4": {
"id": "#faq-4",
"control": "faq-4",
-   "title": "Which platforms is Tor Browser available for?",
+   "title": "Hvilke plattformer finnes Tor-nettleseren på?",
"description": "Tor Browser is currently available on 
Windows, Linux and macOS (OS X). For Android, The Guardian Project maintains 
the Tor-powered apps Orbot and Orfox. There is no official version of Tor for 
iOS yet, though we recommend Onion Browser."
 },
 "faq-5": {

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/support-censorship] Update translations for support-censorship

2018-05-08 Thread translation
commit ff0fc60568ea7f4839b16ad454bc63bf944b96a2
Author: Translation commit bot 
Date:   Wed May 9 00:19:48 2018 +

Update translations for support-censorship
---
 nb.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/nb.json b/nb.json
index 8bd329b02..188e34481 100644
--- a/nb.json
+++ b/nb.json
@@ -20,7 +20,7 @@
 "censorship-4": {
"id": "#censorship-4",
"control": "censorship-4",
-   "title": "I can’t connect to Tor Browser, is my network censored?",
+   "title": "Jeg kan ikke koble til med Tor-nettleseren, er nettverket 
mitt sensurert?",
"description": "You might be on a censored network, 
and so you should try using bridges. Some bridges are built in to Tor Browser, 
and you can use those bridges by choosing \"configure\" (then following the 
prompts) in the Tor Launcher window that pops up when you open Tor Browser for 
the first time. If you need other bridges, you can get them at our ​https://bridges.torproject.org/\;>Bridges website. For more 
information about bridges, see the https://tb-manual.torproject.org/en-US/bridges.html\;>​Tor Browser 
manual."
 },
 "censorship-5": {
@@ -32,7 +32,7 @@
 "censorship-6": {
"id": "#censorship-6",
"control": "censorship-6",
-   "title": "I can’t connect to Tor Browser, is my network censored?",
+   "title": "Jeg kan ikke koble til med Tor-nettleseren, er nettverket 
mitt sensurert?",
"description": "You might be on a censored network, 
and so you should try using bridges. Some bridges are built in to Tor Browser, 
and you can use those bridges by choosing \"configure\" (then following the 
prompts) in the Tor Launcher window that pops up when you open Tor Browser for 
the first time. If you need other bridges, you can get them at our ​https://bridges.torproject.org/\;>Bridges website. For more 
information about bridges, see the https://tb-manual.torproject.org/en-US/bridges.html\;>​Tor Browser 
manual."
 }
 

___
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

2018-05-08 Thread translation
commit 0cbaea4231d84822dc1905744d572c680bec73ec
Author: Translation commit bot 
Date:   Wed May 9 00:16:32 2018 +

Update translations for tor-launcher-network-settings
---
 nb/network-settings.dtd | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/nb/network-settings.dtd b/nb/network-settings.dtd
index 492b6cd85..781a07619 100644
--- a/nb/network-settings.dtd
+++ b/nb/network-settings.dtd
@@ -41,8 +41,8 @@
 
 
 
-
-
+
+
 
 
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor-launcher-properties] Update translations for tor-launcher-properties

2018-05-08 Thread translation
commit 7a71ea732bc3003c9c92120f57ab1b1297b7d4b9
Author: Translation commit bot 
Date:   Wed May 9 00:16:16 2018 +

Update translations for tor-launcher-properties
---
 nb/torlauncher.properties | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/nb/torlauncher.properties b/nb/torlauncher.properties
index 8e97a0dc1..4c50bee54 100644
--- a/nb/torlauncher.properties
+++ b/nb/torlauncher.properties
@@ -26,7 +26,7 @@ torlauncher.error_proxy_addr_missing=Du må spesifisere både 
IP-adresse eller v
 torlauncher.error_proxy_type_missing=Du må velge mellomtjenertypen.
 torlauncher.error_bridges_missing=Du må velge én eller flere broer.
 torlauncher.error_default_bridges_type_missing=Du må velge en tilkoblingstype 
for de angitte broene.
-torlauncher.error_bridgedb_bridges_missing=Please request a bridge.
+torlauncher.error_bridgedb_bridges_missing=Forespør en bro.
 torlauncher.error_bridge_bad_default_type=Det er ingen angitte broer som har 
tilkoblingstypen %S tilgjengelig. Juster innstillingene dine.
 
 torlauncher.bridge_suffix.meek-amazon=(virker i Kina)
@@ -73,6 +73,6 @@ torlauncher.bootstrapWarning.noroute=ingen rute til vert
 torlauncher.bootstrapWarning.ioerror=lese/skrive -feil
 torlauncher.bootstrapWarning.pt_missing=pluggbar transport mangler
 
-torlauncher.nsresult.NS_ERROR_NET_RESET=The connection to the server was lost.
-torlauncher.nsresult.NS_ERROR_CONNECTION_REFUSED=Could not connect to the 
server.
-torlauncher.nsresult.NS_ERROR_PROXY_CONNECTION_REFUSED=Could not connect to 
the proxy.
+torlauncher.nsresult.NS_ERROR_NET_RESET=Tilkoblingen til tjeneren gitt tapt.
+torlauncher.nsresult.NS_ERROR_CONNECTION_REFUSED=Kunne ikke koble til tjeneren.
+torlauncher.nsresult.NS_ERROR_PROXY_CONNECTION_REFUSED=Kunne ikke koble til 
mellomtjeneren.

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] More unit tests for addressmap_get_virtual_address().

2018-05-08 Thread nickm
commit 24ba5fd748a9a27a6069312961843d5f8f662f93
Author: Nick Mathewson 
Date:   Tue May 1 15:28:42 2018 -0400

More unit tests for addressmap_get_virtual_address().

Previously the coverage on this function was mostly accidental,
coming as it did from test_entryconn.c.  These new tests use mocking
to ensure that we actually hit the different failure and retry cases
of addressmap_get_virtual_address(), and make our test coverage a
bit more deterministic.

Closes ticket 25993.
---
 changes/ticket25993  |   4 ++
 src/ext/rust |   2 +-
 src/test/test_addr.c | 154 +++
 3 files changed, 159 insertions(+), 1 deletion(-)

diff --git a/changes/ticket25993 b/changes/ticket25993
new file mode 100644
index 0..8eafcd181
--- /dev/null
+++ b/changes/ticket25993
@@ -0,0 +1,4 @@
+  o Minor features (testing):
+- We now have improved testing for addressmap_get_virtual_address()
+  function.  This should improve our test coverage, and make our test
+  coverage more deterministic. Closes ticket 25993.
diff --git a/src/ext/rust b/src/ext/rust
index fbc0c2578..e92c124a4 16
--- a/src/ext/rust
+++ b/src/ext/rust
@@ -1 +1 @@
-Subproject commit fbc0c25785696a25b9cbc09ed645cc8d404ee0f6
+Subproject commit e92c124a41535bd2131b9506a7d95c68c9d8feda
diff --git a/src/test/test_addr.c b/src/test/test_addr.c
index e1a40b7e6..505e1533d 100644
--- a/src/test/test_addr.c
+++ b/src/test/test_addr.c
@@ -8,6 +8,7 @@
 #include "or.h"
 #include "test.h"
 #include "addressmap.h"
+#include "log_test_helpers.h"
 
 /** Mocking replacement: only handles localhost. */
 static int
@@ -941,6 +942,158 @@ test_virtaddrmap(void *data)
   ;
 }
 
+static const char *canned_data = NULL;
+static size_t canned_data_len = 0;
+
+/* Mock replacement for crypto_rand() that returns canned data from
+ * canned_data above. */
+static void
+crypto_canned(char *ptr, size_t n)
+{
+  if (canned_data_len) {
+size_t to_copy = MIN(n, canned_data_len);
+memcpy(ptr, canned_data, to_copy);
+canned_data += to_copy;
+canned_data_len -= to_copy;
+n -= to_copy;
+ptr += to_copy;
+  }
+  if (n) {
+crypto_rand_unmocked(ptr, n);
+  }
+}
+
+static void
+test_virtaddrmap_persist(void *data)
+{
+  (void)data;
+  const char *a, *b, *c;
+  tor_addr_t addr;
+  char *ones = NULL;
+
+  addressmap_init();
+
+  // Try a hostname.
+  a = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME,
+  tor_strdup("foobar.baz"));
+  tt_assert(a);
+  tt_assert(!strcmpend(a, ".virtual"));
+
+  // mock crypto_rand to repeat the same result twice; make sure we get
+  // different outcomes.  (Because even though the odds for receiving the
+  // same 80-bit address twice is only 1/2^40, it could still happen for
+  // some user -- but running our test through 2^40 iterations isn't
+  // reasonable.)
+  canned_data = "1234567890" // the first call returns this.
+"1234567890" // the second call returns this.
+"abcdefghij"; // the third call returns this.
+  canned_data_len = 30;
+  MOCK(crypto_rand, crypto_canned);
+
+  a = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME,
+  tor_strdup("quuxit.baz"));
+  b = addressmap_register_virtual_address(RESOLVED_TYPE_HOSTNAME,
+  tor_strdup("nescio.baz"));
+  tt_assert(a);
+  tt_assert(b);
+  tt_str_op(a, OP_EQ, "gezdgnbvgy3tqojq.virtual");
+  tt_str_op(b, OP_EQ, "mfrggzdfmztwq2lk.virtual");
+
+  // Now try something to get us an ipv4 address
+  UNMOCK(crypto_rand);
+  tt_int_op(0,OP_EQ, parse_virtual_addr_network("192.168.0.0/16",
+AF_INET, 0, NULL));
+  a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
+  tor_strdup("foobar.baz"));
+  tt_assert(a);
+  tt_assert(!strcmpstart(a, "192.168."));
+  tor_addr_parse(, a);
+  tt_int_op(AF_INET, OP_EQ, tor_addr_family());
+
+  b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
+  tor_strdup("quuxit.baz"));
+  tt_str_op(b, OP_NE, a);
+  tt_assert(!strcmpstart(b, "192.168."));
+
+  // Try some canned entropy and verify all the we discard duplicates,
+  // addresses that end with 0, and addresses that end with 255.
+  MOCK(crypto_rand, crypto_canned);
+  canned_data = "\x01\x02\x03\x04" // okay
+"\x01\x02\x03\x04" // duplicate
+"\x03\x04\x00\x00" // bad ending 1
+"\x05\x05\x00\xff" // bad ending 2
+"\x05\x06\x07\xf0"; // okay
+  canned_data_len = 20;
+  a = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
+  tor_strdup("wumble.onion"));
+  b = addressmap_register_virtual_address(RESOLVED_TYPE_IPV4,
+  

[tor-commits] [tor/master] Mark bug cases of addressmap_get_virtual_address as non-covered

2018-05-08 Thread nickm
commit 5162cf50212ed8a55ec4c6c87b60b59348233d0b
Author: Nick Mathewson 
Date:   Tue May 1 15:28:40 2018 -0400

Mark bug cases of addressmap_get_virtual_address as non-covered
---
 src/or/addressmap.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/src/or/addressmap.c b/src/or/addressmap.c
index 96ce27557..133d3f91e 100644
--- a/src/or/addressmap.c
+++ b/src/or/addressmap.c
@@ -959,9 +959,11 @@ addressmap_get_virtual_address(int type)
 char tmp[TOR_ADDR_BUF_LEN];
 tor_addr_to_str(tmp, , sizeof(tmp), 0);
 if (strmap_get(addressmap, tmp)) {
+  // LCOV_EXCL_START
   log_warn(LD_BUG, "%s wasn't in the addressmap, but %s was.",
buf, tmp);
   continue;
+  // LCOV_EXCL_STOP
 }
 
 return tor_strdup(buf);
@@ -970,8 +972,10 @@ addressmap_get_virtual_address(int type)
 log_warn(LD_CONFIG, "Ran out of virtual addresses!");
 return NULL;
   } else {
+// LCOV_EXCL_START
 log_warn(LD_BUG, "Called with unsupported address type (%d)", type);
 return NULL;
+// LCOV_EXCL_STOP
   }
 }
 



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Merge branch 'ticket25993_squashed'

2018-05-08 Thread nickm
commit a0f051137de293342d692df1d2cfa1386e5e7769
Merge: 26990f3ad 24ba5fd74
Author: Nick Mathewson 
Date:   Tue May 8 20:09:42 2018 -0400

Merge branch 'ticket25993_squashed'

 changes/ticket25993  |   4 ++
 src/or/addressmap.c  |   4 ++
 src/test/test_addr.c | 154 +++
 3 files changed, 162 insertions(+)

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Merge remote-tracking branch 'hello71/bug23883'

2018-05-08 Thread nickm
commit 26990f3adc06d6907029d4580abdf3488153737e
Merge: 6bfa87d3a 2a3998a2e
Author: Nick Mathewson 
Date:   Tue May 8 20:05:35 2018 -0400

Merge remote-tracking branch 'hello71/bug23883'

 doc/HACKING/HelpfulTools.md | 16 
 1 file changed, 16 insertions(+)

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Add Travis CI instructions. fixes #23883

2018-05-08 Thread nickm
commit 2a3998a2e89882715611d4bd94e0e88fb1e1797c
Author: Alex Xu (Hello71) 
Date:   Sat Apr 28 19:51:29 2018 -0400

Add Travis CI instructions. fixes #23883
---
 doc/HACKING/HelpfulTools.md | 16 
 1 file changed, 16 insertions(+)

diff --git a/doc/HACKING/HelpfulTools.md b/doc/HACKING/HelpfulTools.md
index f919d08ec..a0795076e 100644
--- a/doc/HACKING/HelpfulTools.md
+++ b/doc/HACKING/HelpfulTools.md
@@ -4,6 +4,22 @@ Useful tools
 These aren't strictly necessary for hacking on Tor, but they can help track
 down bugs.
 
+Travis CI
+-
+It's CI. Looks like this: https://travis-ci.org/torproject/tor.
+
+Runs automatically on Pull Requests sent to torproject/tor. You can set it up
+for your fork to build commits outside of PRs too:
+
+1. sign up for GitHub: https://github.com/join
+2. fork https://github.com/torproject/tor:
+   https://help.github.com/articles/fork-a-repo/
+3. follow 
https://docs.travis-ci.com/user/getting-started/#To-get-started-with-Travis-CI.
+   skip steps involving `.travis.yml` (we already have one).
+
+Builds should show up on the web at travis-ci.com and on IRC at #tor-ci on
+OFTC. If they don't, ask #tor-dev (also on OFTC).
+
 Jenkins
 ---
 



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/support-topics] Update translations for support-topics

2018-05-08 Thread translation
commit 90605b52c45969f6f28354fb7a3e4b021377ba72
Author: Translation commit bot 
Date:   Tue May 8 23:50:33 2018 +

Update translations for support-topics
---
 nb.json | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/nb.json b/nb.json
index ce0dc7d2e..409b59a65 100644
--- a/nb.json
+++ b/nb.json
@@ -31,8 +31,8 @@
 },
 "censorship": {
"path": "#censorship",
-   "control": "censorship",
-   "label": "Censorship"
+   "control": "sensur",
+   "label": "Sensur"
 },
 "https": {
"path": "#https",
@@ -52,6 +52,6 @@
 "misc": {
"path": "#misc",
"control": "misc",
-   "label": "Misc"
+   "label": "Ymse"
 }
 }

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/support-tbb] Update translations for support-tbb

2018-05-08 Thread translation
commit be7e8d6e6f2fd6fb8a165d3680e6b7c5b64ed640
Author: Translation commit bot 
Date:   Tue May 8 23:50:25 2018 +

Update translations for support-tbb
---
 nb.json | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/nb.json b/nb.json
index b80b4f135..3908f8f67 100644
--- a/nb.json
+++ b/nb.json
@@ -44,7 +44,7 @@
 "tbb-7-1": {
"id": "#tbb-7-1",
"control": "tbb-7-1",
-   "title": "I’m having trouble using features on Facebook, Twitter, or 
some other website when I’m using Tor Browser.",
+   "title": "Jeg har problemer med noen funksjoner på Facebook, Twitter, 
eller en annen nettside når jeg bruker Tor-nettleseren.",
"description": "Sometimes Javascript-heavy websites 
can have functional issues over Tor Browser. The simplest fix is to click on 
the \"onion menu,\" then click on the security slider. Set your security to 
\"low.\""
 },
 "tbb-8": {
@@ -86,7 +86,7 @@
 "tbb-14": {
"id": "#tbb-14",
"control": "tbb-14",
-   "title": "Should I install a new add-on or extension in Tor Browser, 
like AdBlock Plus or uBlock Origin?",
+   "title": "Bør jeg installere et nytt tillegg eller utvidelse i 
Tor-nettleseren, som AdBlock Plus eller uBlock Origin?",
"description": "It's strongly discouraged to install 
new add-ons in Tor Browser, because they can compromise both your privacy and 
your security. Plus, Tor Browser already comes installed with two add-ons — 
HTTPS Everywhere and NoScript — which give you added protection."
 },
 "tbb-15": {
@@ -116,7 +116,7 @@
 "tbb-19": {
"id": "#tbb-19",
"control": "tbb-19",
-   "title": "I can’t connect to Tor Browser, is my network censored?",
+   "title": "Jeg kan ikke koble til med Tor-nettleseren, er nettverket 
mitt sensurert?",
"description": "You might be on a censored network, 
and so you should try using bridges. Some bridges are built in to Tor Browser, 
and you can use those bridges by choosing \"configure\" (then following the 
prompts) in the Tor Launcher window that pops up when you open Tor Browser for 
the first time. If you need other bridges, you can get them at our ​https://bridges.torproject.org/\;>Bridges website. For more 
information about bridges, see the https://tb-manual.torproject.org/en-US/bridges.html\;>​Tor Browser 
manual."
 },
 "tbb-20": {
@@ -128,7 +128,7 @@
 "tbb-21": {
"id": "#tbb-21",
"control": "tbb-21",
-   "title": "How do I view Tor Browser message log?",
+   "title": "Hvordan viser jeg Tor-nettleserens meldingslogg?",
"description": "Click the button labelled \"Copy Tor 
Log To Clipboard\" that appears in the dialog window when Tor Browser is first 
connecting to the network. If Tor Browser is already open, click on the 
Torbutton icon (the small green onion at the top-left of the screen), then 
\"Open Network Settings\", then \"Copy Tor Log To Clipboard.\". Once you have 
copied the log, you will be able to paste it into a text editor or email 
client."
 },
 "tbb-22": {

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/support-tormobile] Update translations for support-tormobile

2018-05-08 Thread translation
commit b592b9891b5c5a13ab3e833491d03caca627242d
Author: Translation commit bot 
Date:   Tue May 8 23:50:48 2018 +

Update translations for support-tormobile
---
 nb.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nb.json b/nb.json
index fe3593d9a..0f5bb7b3b 100644
--- a/nb.json
+++ b/nb.json
@@ -26,7 +26,7 @@
  "tormobile-5": {
"id": "#tormobile-5",
"control": "tormobile-5",
-   "title": "When is Tor Browser for Android being released?",
+   "title": "NÃ¥r slipper Tor-nettleseren for Android?",
"description": "We are currently working on Tor 
Browser for Android, and you may see alpha releases appear over the coming 
months. Please watch our  https://blog.torproject.org\;>blog for future announcements 
and details regarding this project."
  }
 }

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/support-faq] Update translations for support-faq

2018-05-08 Thread translation
commit 51692eb4b292aa8aef00bab3855bc0d6409bb062
Author: Translation commit bot 
Date:   Tue May 8 23:49:54 2018 +

Update translations for support-faq
---
 nb.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nb.json b/nb.json
index 058ee90af..fa464d008 100644
--- a/nb.json
+++ b/nb.json
@@ -14,7 +14,7 @@
 "faq-3": {
"id": "#faq-3",
"control": "faq-3",
-   "title": "Should I install a new add-on or extension in Tor Browser, 
like AdBlock Plus or uBlock Origin?",
+   "title": "Bør jeg installere et nytt tillegg eller utvidelse i 
Tor-nettleseren, som AdBlock Plus eller uBlock Origin?",
"description": "It's strongly discouraged to install 
new add-ons in Tor Browser, because they can compromise both your privacy and 
your security. Plus, Tor Browser already comes installed with two add-ons — 
HTTPS Everywhere and NoScript — which give you added protection."
 },
 "faq-4": {

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/support-miscellaneous] Update translations for support-miscellaneous

2018-05-08 Thread translation
commit 561217fc1e607c1d7d6ad2c7019600ccd0c01a08
Author: Translation commit bot 
Date:   Tue May 8 23:50:18 2018 +

Update translations for support-miscellaneous
---
 nb.json | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/nb.json b/nb.json
index 491d114c0..6e8428efc 100644
--- a/nb.json
+++ b/nb.json
@@ -32,7 +32,7 @@
 "misc-6": {
"id": "#misc-6",
"control": "misc-6",
-   "title": "Does Tor keep logs?",
+   "title": "Beholder Tor logger?",
"description": "Tor doesn't keep any logs that could 
identify a particular user. We do take some safe measurements of how the 
network functions, which you can check out at https://metrics.torproject.org/\;>​Tor Metrics."
 },
 "misc-7": {
@@ -50,7 +50,7 @@
 "misc-9": {
"id": "#misc-9",
"control": "misc-9",
-   "title": "I'm having a problem updating or using Vidalia.",
+   "title": "Jeg har et problem med å oppdatere eller bruke Vidalia.",
"description": "Vidalia is no longer maintained or 
supported. A large portion of the features Vidalia offered have now been 
integrated into Tor Browser itself."
 },
 "misc-10": {
@@ -86,7 +86,7 @@
 "misc-15": {
"id": "#misc-15",
"control": "misc-15",
-   "title": "How can I donate to Tor Project?",
+   "title": "Hvordan kan jeg donere til Tor-prosjektet?",
"description": "Thank you for your support! You can 
find more information about donating on our https://donate.torproject.org/donor-faq\;>​donor FAQe."
  }
 }

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Update rust submodule.

2018-05-08 Thread nickm
commit 6bfa87d3aabd9dae87f0bcb2f456b926e58ed157
Author: Nick Mathewson 
Date:   Tue May 8 18:51:31 2018 -0400

Update rust submodule.
---
 src/ext/rust | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ext/rust b/src/ext/rust
index a870933f6..e92c124a4 16
--- a/src/ext/rust
+++ b/src/ext/rust
@@ -1 +1 @@
-Subproject commit a870933f6b20fc9c47a13e9d980d56b49e30ddb5
+Subproject commit e92c124a41535bd2131b9506a7d95c68c9d8feda

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] rust: Add crypto crate and implement Rust wrappers for SHA2 code.

2018-05-08 Thread nickm
commit af182d4ab51d6a1a70559bbdcd4ab842aa855684
Author: Isis Lovecruft 
Date:   Sat Apr 21 01:01:04 2018 +

rust: Add crypto crate and implement Rust wrappers for SHA2 code.

 * FIXES #24659: https://bugs.torproject.org/24659
---
 configure.ac   |   5 +-
 src/common/crypto_digest.c |  15 +-
 src/rust/Cargo.lock|  35 
 src/rust/Cargo.toml|  11 +-
 src/rust/crypto/Cargo.toml |  21 ++
 src/rust/crypto/digests/mod.rs |   7 +
 src/rust/crypto/digests/sha2.rs| 213 
 src/rust/crypto/lib.rs |  36 
 src/rust/external/Cargo.toml   |   3 +
 src/rust/external/crypto_digest.rs | 402 +
 src/rust/external/lib.rs   |   4 +-
 src/rust/include.am|   5 +
 12 files changed, 752 insertions(+), 5 deletions(-)

diff --git a/configure.ac b/configure.ac
index 387fc6fbe..3bf436203 100644
--- a/configure.ac
+++ b/configure.ac
@@ -306,7 +306,10 @@ fi
 AM_CONDITIONAL(USEPYTHON, [test "x$PYTHON" != "x"])
 
 dnl List all external rust crates we depend on here. Include the version
-rust_crates="libc-0.2.39"
+rust_crates=" \
+digest-0.7.2 \
+libc-0.2.39 \
+"
 AC_SUBST(rust_crates)
 
 ifdef([AC_C_FLEXIBLE_ARRAY_MEMBER], [
diff --git a/src/common/crypto_digest.c b/src/common/crypto_digest.c
index f7163de13..9f9a1a1e2 100644
--- a/src/common/crypto_digest.c
+++ b/src/common/crypto_digest.c
@@ -268,7 +268,11 @@ crypto_digest_new(void)
 }
 
 /** Allocate and return a new digest object to compute 256-bit digests
- * using algorithm. */
+ * using algorithm.
+ *
+ * C_RUST_COUPLED: `external::crypto_digest::crypto_digest256_new`
+ * C_RUST_COUPLED: `crypto::digest::Sha256::default`
+ */
 crypto_digest_t *
 crypto_digest256_new(digest_algorithm_t algorithm)
 {
@@ -298,6 +302,9 @@ crypto_digest_free_(crypto_digest_t *digest)
 }
 
 /** Add len bytes from data to the digest object.
+ *
+ * C_RUST_COUPLED: `external::crypto_digest::crypto_digest_add_bytess`
+ * C_RUST_COUPLED: `crypto::digest::Sha256::process`
  */
 void
 crypto_digest_add_bytes(crypto_digest_t *digest, const char *data,
@@ -335,6 +342,9 @@ crypto_digest_add_bytes(crypto_digest_t *digest, const char 
*data,
 /** Compute the hash of the data that has been passed to the digest
  * object; write the first out_len bytes of the result to out.
  * out_len must be \<= DIGEST512_LEN.
+ *
+ * C_RUST_COUPLED: `external::crypto_digest::crypto_digest_get_digest`
+ * C_RUST_COUPLED: `impl digest::FixedOutput for Sha256`
  */
 void
 crypto_digest_get_digest(crypto_digest_t *digest,
@@ -383,6 +393,9 @@ crypto_digest_get_digest(crypto_digest_t *digest,
 
 /** Allocate and return a new digest object with the same state as
  * digest
+ *
+ * C_RUST_COUPLED: `external::crypto_digest::crypto_digest_dup`
+ * C_RUST_COUPLED: `impl Clone for crypto::digest::Sha256`
  */
 crypto_digest_t *
 crypto_digest_dup(const crypto_digest_t *digest)
diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock
index 2ac32809d..ddbc0ac2b 100644
--- a/src/rust/Cargo.lock
+++ b/src/rust/Cargo.lock
@@ -1,8 +1,35 @@
 [[package]]
+name = "crypto"
+version = "0.0.1"
+dependencies = [
+ "digest 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "external 0.0.1",
+ "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smartlist 0.0.1",
+]
+
+[[package]]
+name = "digest"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index;
+dependencies = [
+ "generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "external"
 version = "0.0.1"
 dependencies = [
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smartlist 0.0.1",
+]
+
+[[package]]
+name = "generic-array"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index;
+dependencies = [
+ "typenum 1.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -87,7 +114,15 @@ dependencies = [
  "tor_log 0.1.0",
 ]
 
+[[package]]
+name = "typenum"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index;
+
 [metadata]
+"checksum digest 0.7.2 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"00a49051fef47a72c9623101b19bd71924a45cca838826caae3eaa4d00772603"
+"checksum generic-array 0.9.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
 "checksum libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)" 
= "f54263ad99207254cf58b5f701ecb432c717445ea2ee8af387334bdd1a03fdff"
 "checksum rand 0.5.0-pre.1 
(registry+https://github.com/rust-lang/crates.io-index)" = 
"7d7a7728c20bfd9fcc6e713e748e787c3d00e5ffd139b3ad1b5be92c5dfbaad5"
 "checksum rand_core 0.1.0 
(registry+https://github.com/rust-lang/crates.io-index)" = 

[tor-commits] [stem/master] Example of v3 hidden services in create_ephemeral_hidden_service docs

2018-05-08 Thread atagar
commit 07bf3c00a26a77a14a1ba6202c5d00b2927e6161
Author: Damian Johnson 
Date:   Sun May 6 11:45:44 2018 -0700

Example of v3 hidden services in create_ephemeral_hidden_service docs

Our 'key_type / key_content' distinction is confusing. I'm just surfacing 
tor's
fields and I see what they're going for, but none the less as a user this 
field
overloading is weird.

Providing an example for how to create a new v3 hidden service.
---
 stem/control.py | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/stem/control.py b/stem/control.py
index 83304cea..fd9aa8dc 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -2874,9 +2874,19 @@ class Controller(BaseController):
   })
 
 To create a **version 3** service simply specify **ED25519-V3** as the
-key_type, and to create a **version 2** service use **RSA1024**. The
+our key type, and to create a **version 2** service use **RSA1024**. The
 default version of newly created hidden services is based on the
-**HiddenServiceVersion** value in your torrc.
+**HiddenServiceVersion** value in your torrc...
+
+::
+
+  response = controller.create_ephemeral_hidden_service(
+80,
+key_content = 'ED25519-V3',
+await_publication = True,
+  )
+
+  print('service established at %s.onion' % response.service_id)
 
 .. versionadded:: 1.4.0
 

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Drop extra join/split

2018-05-08 Thread atagar
commit c178f932b54e85230e312aeda040a9de1b65283c
Author: Damian Johnson 
Date:   Tue May 8 12:51:57 2018 -0700

Drop extra join/split

We joined the section lines only to immediately split them back apart.
---
 stem/directory.py | 17 +++--
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/stem/directory.py b/stem/directory.py
index cab0f30c..014d07a5 100644
--- a/stem/directory.py
+++ b/stem/directory.py
@@ -75,13 +75,13 @@ FALLBACK_EXTRAINFO = re.compile('/\* extrainfo=([0-1]) \*/')
 FALLBACK_IPV6 = re.compile('" ipv6=\[([\da-f:]+)\]:(\d+)"')
 
 
-def _match_with(content, regexes, required = None):
+def _match_with(lines, regexes, required = None):
   """
   Scans the given content against a series of regex matchers, providing back a
   mapping of regexes to their capture groups. This maping is with the value if
   the regex has just a single capture group, and a tuple otherwise.
 
-  :param str content: text to parse
+  :param list lines: text to parse
   :param list regexes: regexes to match against
   :param list required: matches that must be in the content
 
@@ -90,14 +90,11 @@ def _match_with(content, regexes, required = None):
   :raises: **ValueError** if a required match is not present
   """
 
-  if isinstance(content, bytes):
-content = str_tools._to_unicode(content)
-
   matches = {}
 
-  for line in content.splitlines():
+  for line in lines:
 for matcher in regexes:
-  m = matcher.search(line)
+  m = matcher.search(str_tools._to_unicode(line))
 
   if m:
 match_groups = m.groups()
@@ -106,7 +103,7 @@ def _match_with(content, regexes, required = None):
   if required:
 for required_matcher in required:
   if required_matcher not in matches:
-raise ValueError('Failed to parse mandatory data from:\n\n%s' % 
content)
+raise ValueError('Failed to parse mandatory data from:\n\n%s' % 
'\n'.join(lines))
 
   return matches
 
@@ -277,7 +274,7 @@ class Authority(Directory):
 
   if section:
 try:
-  matches = _match_with('\n'.join(section), (AUTHORITY_NAME, 
AUTHORITY_V3IDENT, AUTHORITY_IPV6, AUTHORITY_ADDR), required = (AUTHORITY_NAME, 
AUTHORITY_ADDR))
+  matches = _match_with(section, (AUTHORITY_NAME, AUTHORITY_V3IDENT, 
AUTHORITY_IPV6, AUTHORITY_ADDR), required = (AUTHORITY_NAME, AUTHORITY_ADDR))
   nickname, or_port = matches.get(AUTHORITY_NAME)
   address, dir_port, fingerprint = matches.get(AUTHORITY_ADDR)
 
@@ -448,7 +445,7 @@ class Fallback(Directory):
 
   if section:
 try:
-  matches = _match_with('\n'.join(section), (FALLBACK_ADDR, 
FALLBACK_NICKNAME, FALLBACK_EXTRAINFO, FALLBACK_IPV6), required = 
(FALLBACK_ADDR,))
+  matches = _match_with(section, (FALLBACK_ADDR, FALLBACK_NICKNAME, 
FALLBACK_EXTRAINFO, FALLBACK_IPV6), required = (FALLBACK_ADDR,))
   address, dir_port, or_port, fingerprint = matches[FALLBACK_ADDR]
 
   results[fingerprint] = Fallback(



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Drop _from_str() helpers

2018-05-08 Thread atagar
commit 6240c44e89867de2ea436a614a5458ff31ffb3d9
Author: Damian Johnson 
Date:   Tue May 8 12:46:01 2018 -0700

Drop _from_str() helpers

Our two Directory subclasses had almost identical _from_str() helper. 
Replacing
them with a single more generic _match_with() helper.
---
 stem/directory.py   | 183 +---
 test/unit/directory/fallback.py |  37 ++--
 2 files changed, 85 insertions(+), 135 deletions(-)

diff --git a/stem/directory.py b/stem/directory.py
index b638a354..e360ead6 100644
--- a/stem/directory.py
+++ b/stem/directory.py
@@ -76,6 +76,42 @@ FALLBACK_EXTRAINFO = re.compile('/\* extrainfo=([0-1]) \*/')
 FALLBACK_IPV6 = re.compile('" ipv6=\[([\da-f:]+)\]:(\d+)"')
 
 
+def _match_with(content, regexes, required = None):
+  """
+  Scans the given content against a series of regex matchers, providing back a
+  mapping of regexes to their capture groups. This maping is with the value if
+  the regex has just a single capture group, and a tuple otherwise.
+
+  :param str content: text to parse
+  :param list regexes: regexes to match against
+  :param list required: matches that must be in the content
+
+  :returns: **dict** mapping matchers against their capture groups
+
+  :raises: **ValueError** if a required match is not present
+  """
+
+  if isinstance(content, bytes):
+content = str_tools._to_unicode(content)
+
+  matches = {}
+
+  for line in content.splitlines():
+for matcher in regexes:
+  m = matcher.search(line)
+
+  if m:
+match_groups = m.groups()
+matches[matcher] = match_groups if len(match_groups) > 1 else 
match_groups[0]
+
+  if required:
+for required_matcher in required:
+  if required_matcher not in matches:
+raise ValueError('Failed to parse mandatory data from:\n\n%s' % 
content)
+
+  return matches
+
+
 class Directory(object):
   """
   Relay we can contact for descriptor information.
@@ -207,9 +243,9 @@ class Authority(Directory):
 
   def __init__(self, address = None, or_port = None, dir_port = None, 
fingerprint = None, nickname = None, orport_v6 = None, v3ident = None, 
is_bandwidth_authority = False):
 super(Authority, self).__init__(address, or_port, dir_port, fingerprint, 
nickname, orport_v6)
-identifier = '%s (%s)' % (fingerprint, nickname) if nickname else 
fingerprint
 
 if v3ident and not tor_tools.is_valid_fingerprint(v3ident):
+  identifier = '%s (%s)' % (fingerprint, nickname) if nickname else 
fingerprint
   raise ValueError('%s has an invalid v3ident: %s' % (identifier, v3ident))
 
 self.v3ident = v3ident
@@ -233,69 +269,35 @@ class Authority(Directory):
 results = {}
 
 while lines:
+  # Entries look like...
+  #
+  # "moria1 orport=9101 "
+  #   "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
+  #   "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
+
   section = Authority._pop_section(lines)
 
   if section:
 try:
-  authority = Authority._from_str('\n'.join(section))
-  results[authority.nickname] = authority
+  matches = _match_with('\n'.join(section), (AUTHORITY_NAME, 
AUTHORITY_V3IDENT, AUTHORITY_IPV6, AUTHORITY_ADDR), required = (AUTHORITY_NAME, 
AUTHORITY_ADDR))
+  nickname, or_port = matches.get(AUTHORITY_NAME)
+  address, dir_port, fingerprint = matches.get(AUTHORITY_ADDR)
+
+  results[nickname] = Authority(
+address = address,
+or_port = or_port,
+dir_port = dir_port,
+fingerprint = fingerprint.replace(' ', ''),
+nickname = nickname,
+orport_v6 = matches.get(AUTHORITY_IPV6),
+v3ident = matches.get(AUTHORITY_V3IDENT),
+  )
 except ValueError as exc:
   raise IOError(str(exc))
 
 return results
 
   @staticmethod
-  def _from_str(content):
-"""
-Parses authority from its textual representation. For example...
-
-::
-
-  "moria1 orport=9101 "
-"v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
-"128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
-
-:param str content: text to parse
-
-:returns: :class:`~stem.directory.Authority` in the text
-
-:raises: **ValueError** if content is malformed
-"""
-
-if isinstance(content, bytes):
-  content = str_tools._to_unicode(content)
-
-matches = {}
-
-for line in content.splitlines():
-  for matcher in (AUTHORITY_NAME, AUTHORITY_V3IDENT, AUTHORITY_IPV6, 
AUTHORITY_ADDR):
-m = matcher.match(line.strip())
-
-if m:
-  match_groups = m.groups()
-  matches[matcher] = match_groups if len(match_groups) > 1 else 
match_groups[0]
-
-if AUTHORITY_NAME not in matches:
-  raise ValueError('Unable to parse the name and orport from:\n\n%s' % 
content)
-elif AUTHORITY_ADDR not in matches:
-  raise 

[tor-commits] [stem/master] Move attribute validation into Directory constructors

2018-05-08 Thread atagar
commit cdffc5a9c81145877907ec0135c45d24e6676ae6
Author: Damian Johnson 
Date:   Tue May 8 11:31:11 2018 -0700

Move attribute validation into Directory constructors

Doing validation in the constructors not only makes sense, but lets us
deduplicate this.
---
 stem/directory.py| 90 
 test/unit/directory/authority.py |  6 +--
 test/unit/directory/fallback.py  | 17 
 3 files changed, 47 insertions(+), 66 deletions(-)

diff --git a/stem/directory.py b/stem/directory.py
index c70cbecf..acd24a80 100644
--- a/stem/directory.py
+++ b/stem/directory.py
@@ -102,9 +102,22 @@ class Directory(object):
   """
 
   def __init__(self, address, or_port, dir_port, fingerprint, nickname):
+identifier = '%s (%s)' % (fingerprint, nickname) if nickname else 
fingerprint
+
+if not connection.is_valid_ipv4_address(address):
+  raise ValueError('%s has an invalid IPv4 address: %s' % (identifier, 
address))
+elif not connection.is_valid_port(or_port):
+  raise ValueError('%s has an invalid ORPort: %s' % (identifier, or_port))
+elif not connection.is_valid_port(dir_port):
+  raise ValueError('%s has an invalid DirPort: %s' % (identifier, 
dir_port))
+elif not tor_tools.is_valid_fingerprint(fingerprint):
+  raise ValueError('%s has an invalid fingerprint: %s' % (identifier, 
fingerprint))
+elif nickname and not tor_tools.is_valid_nickname(nickname):
+  raise ValueError('%s has an invalid nickname: %s' % (fingerprint, 
nickname))
+
 self.address = address
-self.or_port = or_port
-self.dir_port = dir_port
+self.or_port = int(or_port)
+self.dir_port = int(dir_port)
 self.fingerprint = fingerprint
 self.nickname = nickname
 
@@ -183,6 +196,11 @@ class Authority(Directory):
 
   def __init__(self, address = None, or_port = None, dir_port = None, 
fingerprint = None, nickname = None, v3ident = None, is_bandwidth_authority = 
False):
 super(Authority, self).__init__(address, or_port, dir_port, fingerprint, 
nickname)
+identifier = '%s (%s)' % (fingerprint, nickname) if nickname else 
fingerprint
+
+if v3ident and not tor_tools.is_valid_fingerprint(v3ident):
+  raise ValueError('%s has an invalid v3ident: %s' % (identifier, v3ident))
+
 self.v3ident = v3ident
 self.is_bandwidth_authority = is_bandwidth_authority
 
@@ -253,33 +271,14 @@ class Authority(Directory):
 
 nickname, or_port = matches.get(AUTHORITY_NAME)
 v3ident = matches.get(AUTHORITY_V3IDENT)
-orport_v6 = matches.get(AUTHORITY_IPV6)  # TODO: add this to stem's data?
+# orport_v6 = matches.get(AUTHORITY_IPV6)  # TODO: add this to stem's data?
 address, dir_port, fingerprint = matches.get(AUTHORITY_ADDR)
 
-fingerprint = fingerprint.replace(' ', '')
-
-if not connection.is_valid_ipv4_address(address):
-  raise ValueError('%s has an invalid IPv4 address: %s' % (nickname, 
address))
-elif not connection.is_valid_port(or_port):
-  raise ValueError('%s has an invalid or_port: %s' % (nickname, or_port))
-elif not connection.is_valid_port(dir_port):
-  raise ValueError('%s has an invalid dir_port: %s' % (nickname, dir_port))
-elif not tor_tools.is_valid_fingerprint(fingerprint):
-  raise ValueError('%s has an invalid fingerprint: %s' % (nickname, 
fingerprint))
-elif nickname and not tor_tools.is_valid_nickname(nickname):
-  raise ValueError('%s has an invalid nickname: %s' % (nickname, nickname))
-elif orport_v6 and not connection.is_valid_ipv6_address(orport_v6[0]):
-  raise ValueError('%s has an invalid IPv6 address: %s' % (nickname, 
orport_v6[0]))
-elif orport_v6 and not connection.is_valid_port(orport_v6[1]):
-  raise ValueError('%s has an invalid ORPort for its IPv6 endpoint: %s' % 
(nickname, orport_v6[1]))
-elif v3ident and not tor_tools.is_valid_fingerprint(v3ident):
-  raise ValueError('%s has an invalid v3ident: %s' % (nickname, v3ident))
-
 return Authority(
   address = address,
-  or_port = int(or_port),
-  dir_port = int(dir_port),
-  fingerprint = fingerprint,
+  or_port = or_port,
+  dir_port = dir_port,
+  fingerprint = fingerprint.replace(' ', ''),
   nickname = nickname,
   v3ident = v3ident,
 )
@@ -353,9 +352,18 @@ class Fallback(Directory):
 
   def __init__(self, address = None, or_port = None, dir_port = None, 
fingerprint = None, nickname = None, has_extrainfo = False, orport_v6 = None, 
header = None):
 super(Fallback, self).__init__(address, or_port, dir_port, fingerprint, 
nickname)
+identifier = '%s (%s)' % (fingerprint, nickname) if nickname else 
fingerprint
+
+if orport_v6:
+  if not isinstance(orport_v6, tuple) or len(orport_v6) != 2:
+raise ValueError('%s orport_v6 should be a two value tuple: %s' % 
(identifier, str(orport_v6)))
+  elif not connection.is_valid_ipv6_address(orport_v6[0]):
+

[tor-commits] [stem/master] Replace sys.exc_info() calls

2018-05-08 Thread atagar
commit 8d2440c859ff58a1250abfbc8ce932c8ee75b04b
Author: Damian Johnson 
Date:   Tue May 8 12:48:48 2018 -0700

Replace sys.exc_info() calls

Huh. Not sure why we did this. Probably overzealous copy-paste.
---
 stem/directory.py | 7 ++-
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/stem/directory.py b/stem/directory.py
index e360ead6..cab0f30c 100644
--- a/stem/directory.py
+++ b/stem/directory.py
@@ -40,7 +40,6 @@ as follows...
 
 import os
 import re
-import sys
 
 import stem.util.conf
 
@@ -259,8 +258,7 @@ class Authority(Directory):
   def from_remote(timeout = 60):
 try:
   lines = str_tools._to_unicode(urllib.urlopen(GITWEB_AUTHORITY_URL, 
timeout = timeout).read()).splitlines()
-except:
-  exc = sys.exc_info()[1]
+except Exception as exc:
   raise IOError("Unable to download tor's directory authorities from %s: 
%s" % (GITWEB_AUTHORITY_URL, exc))
 
 if not lines:
@@ -410,8 +408,7 @@ class Fallback(Directory):
   def from_remote(timeout = 60):
 try:
   lines = str_tools._to_unicode(urllib.urlopen(GITWEB_FALLBACK_URL, 
timeout = timeout).read()).splitlines()
-except:
-  exc = sys.exc_info()[1]
+except Exception as exc:
   raise IOError("Unable to download tor's fallback directories from %s: 
%s" % (GITWEB_FALLBACK_URL, exc))
 
 if not lines:



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Deduplicate more of from_remote()

2018-05-08 Thread atagar
commit 4e360223f7567af932b3dd49e28f176c92f78bc8
Author: Damian Johnson 
Date:   Tue May 8 13:10:08 2018 -0700

Deduplicate more of from_remote()

Just tidying up boilerplate so this is more readable.
---
 stem/directory.py | 116 ++
 1 file changed, 56 insertions(+), 60 deletions(-)

diff --git a/stem/directory.py b/stem/directory.py
index 014d07a5..5d1a352d 100644
--- a/stem/directory.py
+++ b/stem/directory.py
@@ -108,6 +108,14 @@ def _match_with(lines, regexes, required = None):
   return matches
 
 
+def _directory_entries(lines, pop_section_func, regexes, required = None):
+  next_section = pop_section_func(lines)
+
+  while next_section:
+yield _match_with(next_section, regexes, required)
+next_section = pop_section_func(lines)
+
+
 class Directory(object):
   """
   Relay we can contact for descriptor information.
@@ -261,34 +269,30 @@ class Authority(Directory):
 if not lines:
   raise IOError('%s did not have any content' % GITWEB_AUTHORITY_URL)
 
-results = {}
+# Entries look like...
+#
+# "moria1 orport=9101 "
+#   "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
+#   "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
 
-while lines:
-  # Entries look like...
-  #
-  # "moria1 orport=9101 "
-  #   "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
-  #   "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
-
-  section = Authority._pop_section(lines)
-
-  if section:
-try:
-  matches = _match_with(section, (AUTHORITY_NAME, AUTHORITY_V3IDENT, 
AUTHORITY_IPV6, AUTHORITY_ADDR), required = (AUTHORITY_NAME, AUTHORITY_ADDR))
-  nickname, or_port = matches.get(AUTHORITY_NAME)
-  address, dir_port, fingerprint = matches.get(AUTHORITY_ADDR)
-
-  results[nickname] = Authority(
-address = address,
-or_port = or_port,
-dir_port = dir_port,
-fingerprint = fingerprint.replace(' ', ''),
-nickname = nickname,
-orport_v6 = matches.get(AUTHORITY_IPV6),
-v3ident = matches.get(AUTHORITY_V3IDENT),
-  )
-except ValueError as exc:
-  raise IOError(str(exc))
+try:
+  results = {}
+
+  for matches in _directory_entries(lines, Authority._pop_section, 
(AUTHORITY_NAME, AUTHORITY_V3IDENT, AUTHORITY_IPV6, AUTHORITY_ADDR), required = 
(AUTHORITY_NAME, AUTHORITY_ADDR)):
+nickname, or_port = matches.get(AUTHORITY_NAME)
+address, dir_port, fingerprint = matches.get(AUTHORITY_ADDR)
+
+results[nickname] = Authority(
+  address = address,
+  or_port = or_port,
+  dir_port = dir_port,
+  fingerprint = fingerprint.replace(' ', ''),
+  nickname = nickname,
+  orport_v6 = matches.get(AUTHORITY_IPV6),
+  v3ident = matches.get(AUTHORITY_V3IDENT),
+)
+except ValueError as exc:
+  raise IOError(str(exc))
 
 return results
 
@@ -425,41 +429,33 @@ class Fallback(Directory):
   else:
 raise IOError('Malformed fallback directory header line: %s' % line)
 
-# human readable comments
+Fallback._pop_section(lines)  # skip human readable comments
 
-Fallback._pop_section(lines)
+# Entries look like...
+#
+# "5.9.110.236:9030 orport=9001 
id=0756B7CD4DFC8182BE23143FAC0642F515182CEB"
+# " ipv6=[2a01:4f8:162:51e2::2]:9001"
+# /* nickname=rueckgrat */
+# /* extrainfo=1 */
 
-# content, everything remaining are fallback directories
-
-results = {}
-
-while lines:
-  # Entries look like...
-  #
-  # "5.9.110.236:9030 orport=9001 
id=0756B7CD4DFC8182BE23143FAC0642F515182CEB"
-  # " ipv6=[2a01:4f8:162:51e2::2]:9001"
-  # /* nickname=rueckgrat */
-  # /* extrainfo=1 */
-
-  section = Fallback._pop_section(lines)
-
-  if section:
-try:
-  matches = _match_with(section, (FALLBACK_ADDR, FALLBACK_NICKNAME, 
FALLBACK_EXTRAINFO, FALLBACK_IPV6), required = (FALLBACK_ADDR,))
-  address, dir_port, or_port, fingerprint = matches[FALLBACK_ADDR]
-
-  results[fingerprint] = Fallback(
-address = address,
-or_port = int(or_port),
-dir_port = int(dir_port),
-fingerprint = fingerprint,
-nickname = matches.get(FALLBACK_NICKNAME),
-has_extrainfo = matches.get(FALLBACK_EXTRAINFO) == '1',
-orport_v6 = matches.get(FALLBACK_IPV6),
-header = header,
-  )
-except ValueError as exc:
-  raise IOError(str(exc))
+try:
+  results = {}
+
+  for matches in _directory_entries(lines, Fallback._pop_section, 
(FALLBACK_ADDR, FALLBACK_NICKNAME, FALLBACK_EXTRAINFO, FALLBACK_IPV6), required 
= (FALLBACK_ADDR,)):
+address, dir_port, or_port, fingerprint = matches[FALLBACK_ADDR]
+
+ 

[tor-commits] [stem/master] Add stem.directory module

2018-05-08 Thread atagar
commit 65a5097ff063bd163c4e1e6ce92b4caf4090ec82
Merge: ffb3ade8 4e360223
Author: Damian Johnson 
Date:   Tue May 8 13:12:02 2018 -0700

Add stem.directory module

When dirauths were a small constant it made sense to co-locate them in the
remote module (the sole spot they were used). But they've grown. With the
addition of fallback directories and from_remote() parsers they're now the 
bulk
of the remote module and way past the point where they deserve their own
module.

Adding a stem.directory module with aliases for backward compatability. Also
shortening the names. With this the module is a *lot* nicer to use. For
instance to list the authorities we're going from...

  for authority in stem.descriptor.remote.DirectoryAuthority.from_cache():
print(authority.nickname)

... to...

  for authority in stem.directory.Authority.from_cache():
print(authority.nickname)

This branch also makes a few additions...

  * Authority class now has the from_cache() and from_remote()
function.

  * Added the orport_v6 attribute to Authorities and removed
is_bandwidth_authority.

* Expanded test coverage.

 docs/_static/example/compare_flags.py  |  15 +-
 .../example/votes_by_bandwidth_authorities.py  |  21 +-
 docs/api/directory.rst |   5 +
 docs/change_log.rst|   9 +-
 setup.py   |   3 +-
 stem/__init__.py   |   1 +
 ...llback_directories.cfg => cached_fallbacks.cfg} |   0
 ...ched_tor_manual.sqlite => cached_manual.sqlite} | Bin
 stem/descriptor/remote.py  | 846 -
 stem/directory.py  | 657 
 stem/manual.py |   2 +-
 stem/prereq.py |  51 +-
 stem/util/__init__.py  |   8 +
 test/integ/descriptor/remote.py|  53 +-
 test/integ/directory/__init__.py   |   8 +
 test/integ/directory/authority.py  |  18 +
 test/integ/directory/fallback.py   |  54 ++
 test/settings.cfg  |   5 +
 test/unit/__init__.py  |   1 +
 test/unit/descriptor/remote.py | 192 +
 test/unit/directory/__init__.py|   8 +
 test/unit/directory/authority.py   |  81 ++
 test/unit/directory/fallback.py| 200 +
 test/unit/installation.py  |   3 +-
 test/unit/tutorial_examples.py |  14 +-
 25 files changed, 1276 insertions(+), 979 deletions(-)



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Deprecate is_bandwidth_authority attribute

2018-05-08 Thread atagar
commit 6e40a303a96fccd2db3e0370efc3d7d4c54d82a4
Author: Damian Johnson 
Date:   Mon May 7 10:57:39 2018 -0700

Deprecate is_bandwidth_authority attribute

This is a moving target that isn't tracked in tor, so I don't think we'll 
track
it in Stem either. Folks can download the votes to check who is/isn't a
bandwidth auth. This is how it's defined (providing bandwidth measurements 
in
votes), after all.
---
 .../example/votes_by_bandwidth_authorities.py  | 14 
 stem/directory.py  | 38 +-
 test/integ/directory/authority.py  | 22 +
 test/unit/directory/authority.py   |  1 -
 4 files changed, 24 insertions(+), 51 deletions(-)

diff --git a/docs/_static/example/votes_by_bandwidth_authorities.py 
b/docs/_static/example/votes_by_bandwidth_authorities.py
index 9504bd94..840d50d8 100644
--- a/docs/_static/example/votes_by_bandwidth_authorities.py
+++ b/docs/_static/example/votes_by_bandwidth_authorities.py
@@ -7,11 +7,10 @@ queries = {}
 downloader = stem.descriptor.remote.DescriptorDownloader()
 
 for authority in stem.directory.Authority.from_cache().values():
-  if authority.is_bandwidth_authority:
-queries[authority.nickname] = downloader.query(
-  '/tor/status-vote/current/authority',
-  endpoints = [(authority.address, authority.dir_port)],
-)
+  queries[authority.nickname] = downloader.query(
+'/tor/status-vote/current/authority',
+endpoints = [(authority.address, authority.dir_port)],
+  )
 
 for authority_name, query in queries.items():
   try:
@@ -25,6 +24,9 @@ for authority_name, query in queries.items():
   else:
 unmeasured += 1
 
-print('  %i measured entries and %i unmeasured' % (measured, unmeasured))
+if measured == 0:
+  print('  %s is not a bandwidth authority' % authority_name)
+else:
+  print('  %i measured entries and %i unmeasured' % (measured, unmeasured))
   except Exception as exc:
 print("  failed to get the vote (%s)" % exc)
diff --git a/stem/directory.py b/stem/directory.py
index 7b78696a..c70cbecf 100644
--- a/stem/directory.py
+++ b/stem/directory.py
@@ -2,7 +2,7 @@
 # See LICENSE for licensing information
 
 """
-Directories with `tor descriptor information
+Directories that provide `relay descriptor information
 <../tutorials/mirror_mirror_on_the_wall.html>`_. At a very high level tor works
 as follows...
 
@@ -60,7 +60,7 @@ except ImportError:
 
 GITWEB_AUTHORITY_URL = 
'https://gitweb.torproject.org/tor.git/plain/src/or/auth_dirs.inc'
 GITWEB_FALLBACK_URL = 
'https://gitweb.torproject.org/tor.git/plain/src/or/fallback_dirs.inc'
-CACHE_PATH = os.path.join(os.path.dirname(__file__), 'cached_fallbacks.cfg')
+FALLBACK_CACHE_PATH = os.path.join(os.path.dirname(__file__), 
'cached_fallbacks.cfg')
 
 AUTHORITY_NAME = re.compile('"(\S+) orport=(\d+) .*"')
 AUTHORITY_V3IDENT = re.compile('"v3ident=([\dA-F]{40}) "')
@@ -78,14 +78,14 @@ FALLBACK_IPV6 = re.compile('" ipv6=\[([\da-f:]+)\]:(\d+)"')
 
 class Directory(object):
   """
-  Relay we can contact for directory information.
+  Relay we can contact for descriptor information.
 
   Our :func:`~stem.directory.Directory.from_cache` and
   :func:`~stem.directory.Directory.from_remote` functions key off a
   different identifier based on our subclass...
 
-* **Authority** keys off the nickname.
-* **Fallback** keys off fingerprints.
+* :class:`~stem.directory.Authority` keys off the nickname.
+* :class:`~stem.directory.Fallback` keys off fingerprints.
 
   This is because authorities are highly static and canonically known by their
   names, whereas fallbacks vary more and don't necessarily have a nickname to
@@ -112,8 +112,8 @@ class Directory(object):
   def from_cache():
 """
 Provides cached Tor directory information. This information is hardcoded
-into Tor and occasionally changes, so the information this provides might
-not necessarily match the latest version of tor.
+into Tor and occasionally changes, so the information provided by this
+method may not necessarily match the latest version of tor.
 
 .. versionadded:: 1.5.0
 
@@ -169,14 +169,16 @@ class Authority(Directory):
   """
   Tor directory authority, a special type of relay `hardcoded into tor
   `_
-  that enumerates the other relays within the network.
+  to enumerate the relays in the network.
 
   .. versionchanged:: 1.3.0
  Added the is_bandwidth_authority attribute.
 
+  .. deprecated:: 1.7.0
+ The is_bandwidth_authority attribute is deprecated and will be removed in
+ the future.
+
   :var str v3ident: identity key fingerprint used to sign votes and consensus
-  :var bool is_bandwidth_authority: **True** if this is a bandwidth authority,
-**False** otherwise
   """
 
   def __init__(self, address = None, or_port = None, dir_port = 

[tor-commits] [stem/master] Separate stem.directory integ tests

2018-05-08 Thread atagar
commit 61a1fe90797814b871c94929b533cf98e7715e30
Author: Damian Johnson 
Date:   Mon May 7 07:40:42 2018 -0700

Separate stem.directory integ tests

Moving the authority and fallback integ tests into their own modules.
---
 test/integ/descriptor/remote.py   | 72 ---
 test/integ/directory/__init__.py  |  8 +
 test/integ/directory/authority.py | 38 +
 test/integ/directory/fallback.py  | 54 +
 test/settings.cfg |  2 ++
 5 files changed, 102 insertions(+), 72 deletions(-)

diff --git a/test/integ/descriptor/remote.py b/test/integ/descriptor/remote.py
index b3553598..0305d069 100644
--- a/test/integ/descriptor/remote.py
+++ b/test/integ/descriptor/remote.py
@@ -245,75 +245,3 @@ class TestDescriptorDownloader(unittest.TestCase):
 self.assertTrue(isinstance(single_query_results[0], 
stem.descriptor.networkstatus.KeyCertificate))
 
 self.assertEqual(2, len(list(multiple_query)))
-
-  @test.require.online
-  def test_authority_cache_is_up_to_date(self):
-"""
-Check if the cached authorities bundled with Stem are up to date or not.
-"""
-
-cached_authorities = stem.descriptor.remote.get_authorities()
-latest_authorities = 
stem.descriptor.remote.DirectoryAuthority.from_remote()
-
-for nickname in cached_authorities:
-  if nickname not in latest_authorities:
-self.fail('%s is no longer a directory authority in tor' % nickname)
-
-for nickname in latest_authorities:
-  if nickname not in cached_authorities:
-self.fail('%s is now a directory authority in tor' % nickname)
-
-# tor doesn't note if an autority is a bwauth or not, so we need to exclude
-# that from our comparison
-
-for attr in ('address', 'or_port', 'dir_port', 'fingerprint', 'nickname', 
'v3ident'):
-  for auth in cached_authorities.values():
-cached_value = getattr(auth, attr)
-latest_value = getattr(latest_authorities[auth.nickname], attr)
-
-if cached_value != latest_value:
-  self.fail('The %s of the %s authority is %s in tor but %s in stem' % 
(attr, auth.nickname, latest_value, cached_value))
-
-  @test.require.online
-  def test_fallback_cache_is_up_to_date(self):
-"""
-Check if the cached fallback directories bundled with Stem are up to date
-or not.
-"""
-
-cached_fallback_directories = 
stem.descriptor.remote.FallbackDirectory.from_cache()
-latest_fallback_directories = 
stem.descriptor.remote.FallbackDirectory.from_remote()
-
-if cached_fallback_directories != latest_fallback_directories:
-  self.fail("Stem's cached fallback directories are out of date. Please 
run 'cache_fallback_directories.py'...\n\n%s" % 
stem.descriptor.remote._fallback_directory_differences(cached_fallback_directories,
 latest_fallback_directories))
-
-  @test.require.online
-  def test_fallback_directory_reachability(self):
-"""
-Fetch information from each fallback directory to confirm that it's
-available.
-"""
-
-# Don't run this test by default. Once upon a time it was fine, but tor has
-# added so many fallbacks now that this takes a looong time. :(
-
-self.skipTest('(skipped by default)')
-return
-
-unsuccessful = {}
-downloader = stem.descriptor.remote.DescriptorDownloader()
-moria1_v3ident = stem.descriptor.remote.get_authorities()['moria1'].v3ident
-
-for fallback_directory in 
stem.descriptor.remote.FallbackDirectory.from_cache().values():
-  try:
-downloader.get_key_certificates(authority_v3idents = moria1_v3ident, 
endpoints = [(fallback_directory.address, fallback_directory.dir_port)]).run()
-  except Exception as exc:
-unsuccessful[fallback_directory] = exc
-
-if unsuccessful:
-  lines = ['We were unable to contact the following fallback 
directories...\n']
-
-  for fallback_directory, exc in unsuccessful.items():
-lines.append('* %s:%s (%s): %s' % (fallback_directory.address, 
fallback_directory.dir_port, fallback_directory.fingerprint, exc))
-
-  self.fail('\n'.join(lines))
diff --git a/test/integ/directory/__init__.py b/test/integ/directory/__init__.py
new file mode 100644
index ..f4e52c12
--- /dev/null
+++ b/test/integ/directory/__init__.py
@@ -0,0 +1,8 @@
+"""
+Integration tests for stem.directory.
+"""
+
+__all__ = [
+  'authority',
+  'fallback',
+]
diff --git a/test/integ/directory/authority.py 
b/test/integ/directory/authority.py
new file mode 100644
index ..fc5eb13e
--- /dev/null
+++ b/test/integ/directory/authority.py
@@ -0,0 +1,38 @@
+"""
+Integration tests for stem.directory.Authority.
+"""
+
+import unittest
+
+import stem.directory
+import test.require
+
+
+class TestAuthority(unittest.TestCase):
+  @test.require.online
+  def test_cache_is_up_to_date(self):
+"""
+Check if the cached authorities we bundle are up to date.
+"""
+
+

[tor-commits] [stem/master] Initial Authority.from_remote() unit tests

2018-05-08 Thread atagar
commit 1d467aee328887fb4259ebc498a6b8ddebc8e81d
Author: Damian Johnson 
Date:   Mon May 7 10:40:31 2018 -0700

Initial Authority.from_remote() unit tests

Adopting a couple Fallback tests for its Authority counterpart. The 
persistance
tests aren't relevant to it (authorities are managed by hand). As for the
from_str() tests I need to give this more thought. Maybe refactor the
directory module a bit first.
---
 test/unit/directory/authority.py |  52 ++
 test/unit/directory/fallback.py  | 110 +++
 2 files changed, 107 insertions(+), 55 deletions(-)

diff --git a/test/unit/directory/authority.py b/test/unit/directory/authority.py
index 4a5f3a12..dcee4916 100644
--- a/test/unit/directory/authority.py
+++ b/test/unit/directory/authority.py
@@ -2,9 +2,29 @@
 Unit tests for stem.directory.Authority.
 """
 
+import io
 import unittest
 
 import stem.directory
+import stem.prereq
+
+try:
+  # added in python 3.3
+  from unittest.mock import patch, Mock
+except ImportError:
+  from mock import patch, Mock
+
+URL_OPEN = 'urllib.request.urlopen' if stem.prereq.is_python_3() else 
'urllib2.urlopen'
+
+AUTHORITY_GITWEB_CONTENT = b"""\
+"moria1 orport=9101 "
+  "v3ident=D586D18309DED4CD6D57C18FDB97EFA96D330566 "
+  "128.31.0.39:9131 9695 DFC3 5FFE B861 329B 9F1A B04C 4639 7020 CE31",
+"tor26 orport=443 "
+  "v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
+  "ipv6=[2001:858:2:2:aabb:0:563b:1526]:443 "
+  "86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
+"""
 
 
 class TestAuthority(unittest.TestCase):
@@ -26,3 +46,35 @@ class TestAuthority(unittest.TestCase):
 second_authority = dict(authority_attr)
 second_authority[attr] = value
 self.assertNotEqual(stem.directory.Authority(**authority_attr), 
stem.directory.Authority(**second_authority))
+
+  def test_from_cache(self):
+authorities = stem.directory.Authority.from_cache()
+self.assertTrue(len(authorities) > 4)
+self.assertEqual('128.31.0.39', authorities['moria1'].address)
+
+  @patch(URL_OPEN, Mock(return_value = io.BytesIO(AUTHORITY_GITWEB_CONTENT)))
+  def test_from_remote(self):
+expected = {
+  'moria1': stem.directory.Authority(
+nickname = 'moria1',
+address = '128.31.0.39',
+or_port = 9101,
+dir_port = 9131,
+fingerprint = '9695DFC35FFEB861329B9F1AB04C46397020CE31',
+v3ident = 'D586D18309DED4CD6D57C18FDB97EFA96D330566',
+  ),
+  'tor26': stem.directory.Authority(
+nickname = 'tor26',
+address = '86.59.21.38',
+or_port = 443,
+dir_port = 80,
+fingerprint = '847B1F850344D7876491A54892F904934E4EB85D',
+v3ident = '14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4',
+  ),
+}
+
+self.assertEqual(expected, stem.directory.Authority.from_remote())
+
+  @patch(URL_OPEN, Mock(return_value = io.BytesIO(b'')))
+  def test_from_remote_empty(self):
+self.assertRaisesRegexp(IOError, 'did not have any content', 
stem.directory.Authority.from_remote)
diff --git a/test/unit/directory/fallback.py b/test/unit/directory/fallback.py
index cd857b9f..1cbff9a3 100644
--- a/test/unit/directory/fallback.py
+++ b/test/unit/directory/fallback.py
@@ -23,7 +23,7 @@ except ImportError:
 
 URL_OPEN = 'urllib.request.urlopen' if stem.prereq.is_python_3() else 
'urllib2.urlopen'
 
-FALLBACK_DIR_CONTENT = b"""\
+FALLBACK_GITWEB_CONTENT = b"""\
 /* type=fallback */
 /* version=2.0.0 */
 /* timestamp=20170526090242 */
@@ -63,6 +63,12 @@ FALLBACK_ENTRY = b"""\
 /* extrainfo=1 */
 """
 
+HEADER = OrderedDict((
+  ('type', 'fallback'),
+  ('version', '2.0.0'),
+  ('timestamp', '20170526090242'),
+))
+
 
 class TestFallback(unittest.TestCase):
   def test_equality(self):
@@ -90,16 +96,12 @@ class TestFallback(unittest.TestCase):
 self.assertNotEqual(stem.directory.Fallback(**fallback_attr), 
stem.directory.Fallback(**second_fallback))
 
   def test_from_cache(self):
-# quick sanity test that we can load cached content
-fallback_directories = stem.directory.Fallback.from_cache()
-self.assertTrue(len(fallback_directories) > 10)
-self.assertEqual('5.39.92.199', 
fallback_directories['0BEA4A88D069753218EAAAD6D22EA87B9A1319D6'].address)
+fallbacks = stem.directory.Fallback.from_cache()
+self.assertTrue(len(fallbacks) > 10)
+self.assertEqual('5.39.92.199', 
fallbacks['0BEA4A88D069753218EAAAD6D22EA87B9A1319D6'].address)
 
-  @patch(URL_OPEN, Mock(return_value = io.BytesIO(FALLBACK_DIR_CONTENT)))
+  @patch(URL_OPEN, Mock(return_value = io.BytesIO(FALLBACK_GITWEB_CONTENT)))
   def test_from_remote(self):
-fallback_directories = stem.directory.Fallback.from_remote()
-header = OrderedDict((('type', 'fallback'), ('version', '2.0.0'), 
('timestamp', '20170526090242')))
-
 expected = {
   '0756B7CD4DFC8182BE23143FAC0642F515182CEB': stem.directory.Fallback(
 address = '5.9.110.236',
@@ 

[tor-commits] [stem/master] Replace get_authorities() with DirectoryAuthority.from_cache()

2018-05-08 Thread atagar
commit fa26e4aad86b5d52a0cb4002afd302cfccebf768
Author: Damian Johnson 
Date:   Fri May 4 12:48:35 2018 -0700

Replace get_authorities() with DirectoryAuthority.from_cache()

Replacing our function for vending directory authority data. Simplifies our 
API
by making us more consistant across our Directory subclasses.
---
 docs/change_log.rst   |   1 +
 stem/descriptor/remote.py | 143 +++---
 2 files changed, 71 insertions(+), 73 deletions(-)

diff --git a/docs/change_log.rst b/docs/change_log.rst
index d10597ea..d5505821 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -57,6 +57,7 @@ The following are only available within Stem's `git repository
 
   * `stem.descriptor.remote `_ can now download 
from relay ORPorts
   * Zstd and lzma compression support (:spec:`1cb56af`)
+  * Added :func:`~stem.descriptor.remote.Directory.from_cache` and 
:func:`~stem.descriptor.remote.Directory.from_remote` to the 
:class:`~stem.descriptor.remote.DirectoryAuthority` subclass.
   * `Fallback directory v2 support 
`_, 
which adds *nickname* and *extrainfo*
   * Added server descriptor's new is_hidden_service_dir attribute
   * Don't retry downloading descriptors when we've timed out
diff --git a/stem/descriptor/remote.py b/stem/descriptor/remote.py
index a656e354..e0b4c21d 100644
--- a/stem/descriptor/remote.py
+++ b/stem/descriptor/remote.py
@@ -50,13 +50,12 @@ content. For example...
 |- get_extrainfo_descriptors - provides present extrainfo descriptors
 +- get_consensus - provides the present consensus or router status entries
 
-  get_authorities - Provides tor directory information.
-
   Directory - Relay we can retrieve directory information from
+| |- from_cache - Provides fallback directories cached with Stem.
+| +- from_remote - Retrieves fallback directories remotely from tor's 
latest commit.
+|
 |- DirectoryAuthority - Information about a tor directory authority
 +- FallbackDirectory - Directory mirror tor uses when authories are 
unavailable
-|- from_cache - Provides fallback directories cached with Stem.
-+- from_remote - Retrieves fallback directories remotely from tor's 
latest commit.
 
   Query - Asynchronous request to download tor descriptors
 |- start - issues the query if it isn't already running
@@ -1022,9 +1021,18 @@ class DescriptorDownloader(object):
 
 class Directory(object):
   """
-  Relay we can contact for directory information
+  Relay we can contact for directory information.
 
-  .. versionadded:: 1.5.0
+  Our :func:`~stem.descriptor.remote.Directory.from_cache` and
+  :func:`~stem.descriptor.remote.Directory.from_remote` functions key off a
+  different identifier based on our subclass...
+
+* **DirectoryAuthority** keys off the nickname.
+* **FallbackDirectory** keys off fingerprints.
+
+  This is because authorities are highly static and canonically known by their
+  names, whereas fallbacks vary more and don't necessarily have a nickname to
+  key off of.
 
   .. versionchanged:: 1.3.0
  Moved nickname from subclasses to this base class.
@@ -1043,6 +1051,53 @@ class Directory(object):
 self.fingerprint = fingerprint
 self.nickname = nickname
 
+  @staticmethod
+  def from_cache():
+"""
+Provides cached Tor directory information. This information is hardcoded
+into Tor and occasionally changes, so the information this provides might
+not necessarily match your version of tor.
+
+.. versionadded:: 1.5.0
+
+.. versionchanged:: 1.7.0
+   Support added to the 
:class:`~stem.descriptor.remote.DirectoryAuthority` class.
+
+:returns: **dict** of **str** identifiers to
+  :class:`~stem.descriptor.remote.Directory` instances
+"""
+
+raise NotImplementedError('Unsupported Operation: this should be 
implemented by the Directory subclass')
+
+  @staticmethod
+  def from_remote(timeout = 60):
+"""
+Reads and parses tor's directory data `from gitweb.torproject.org 
`_.
+Note that while convenient, this reliance on GitWeb means you should alway
+call with a fallback, such as...
+
+::
+
+  try:
+authorities = DirectoryAuthority.from_remote()
+  except IOError:
+authorities = DirectoryAuthority.from_cache()
+
+.. versionadded:: 1.5.0
+
+.. versionchanged:: 1.7.0
+   Support added to the 
:class:`~stem.descriptor.remote.DirectoryAuthority` class.
+
+:param int timeout: seconds to wait before timing out the request
+
+:returns: **dict** of **str** identifiers to their
+  :class:`~stem.descriptor.remote.Directory`
+
+:raises: **IOError** if unable to retrieve the fallback directories
+"""
+
+raise NotImplementedError('Unsupported Operation: this should be 
implemented by the Directory subclass')
+
   def __hash__(self):

[tor-commits] [stem/master] Unit test directory equality

2018-05-08 Thread atagar
commit d893ec53b03bda8fa973e0552c65999b5eb5167f
Author: Damian Johnson 
Date:   Sun May 6 13:03:24 2018 -0700

Unit test directory equality

Now that we've cleaned up our equality checks it's a natural spot to start
testing. Found an interesting bug where 'False' and 'None' values resulted 
in
directories being considered equal.
---
 stem/util/__init__.py|  8 
 test/settings.cfg|  1 +
 test/unit/directory/__init__.py  |  1 +
 test/unit/directory/authority.py | 28 
 test/unit/directory/fallback.py  | 24 
 5 files changed, 62 insertions(+)

diff --git a/stem/util/__init__.py b/stem/util/__init__.py
index 5ccd921a..711f28a5 100644
--- a/stem/util/__init__.py
+++ b/stem/util/__init__.py
@@ -31,6 +31,12 @@ else:
   str_type = unicode
   int_type = long
 
+# Python hashes booleans to zero or one. Usually this would be fine, but since
+# we use hashes for equality checks we need them to be something less common.
+
+TRUE_HASH_VALUE = 4813749
+FALSE_HASH_VALUE = 5826450
+
 
 def datetime_to_unix(timestamp):
   """
@@ -72,6 +78,8 @@ def _hash_attr(obj, *attributes, **kwargs):
   elif isinstance(attr_value, (list, tuple)):
 for entry in attr_value:
   my_hash = (my_hash + hash(entry)) * 1024
+  elif isinstance(attr_value, bool):
+my_hash += TRUE_HASH_VALUE if attr_value else FALSE_HASH_VALUE
   else:
 my_hash += hash(attr_value)
 
diff --git a/test/settings.cfg b/test/settings.cfg
index 2206c7e7..312e3ce9 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -220,6 +220,7 @@ test.unit_tests
 |test.unit.endpoint.TestEndpoint
 |test.unit.version.TestVersion
 |test.unit.manual.TestManual
+|test.unit.directory.authority.TestAuthority
 |test.unit.directory.fallback.TestFallback
 |test.unit.tutorial.TestTutorial
 |test.unit.tutorial_examples.TestTutorialExamples
diff --git a/test/unit/directory/__init__.py b/test/unit/directory/__init__.py
index 78e42d7c..7ca7ea92 100644
--- a/test/unit/directory/__init__.py
+++ b/test/unit/directory/__init__.py
@@ -3,5 +3,6 @@ Unit tests for stem.directory.
 """
 
 __all__ = [
+  'authority',
   'fallback',
 ]
diff --git a/test/unit/directory/authority.py b/test/unit/directory/authority.py
new file mode 100644
index ..4a5f3a12
--- /dev/null
+++ b/test/unit/directory/authority.py
@@ -0,0 +1,28 @@
+"""
+Unit tests for stem.directory.Authority.
+"""
+
+import unittest
+
+import stem.directory
+
+
+class TestAuthority(unittest.TestCase):
+  def test_equality(self):
+authority_attr = {
+  'address': '5.9.110.236',
+  'or_port': 9001,
+  'dir_port': 9030,
+  'fingerprint': '0756B7CD4DFC8182BE23143FAC0642F515182CEB',
+  'nickname': 'rueckgrat',
+  'v3ident': '23D15D965BC35114467363C165C4F724B64B4F66',
+  'is_bandwidth_authority': False,
+}
+
+self.assertEqual(stem.directory.Authority(**authority_attr), 
stem.directory.Authority(**authority_attr))
+
+for attr in authority_attr:
+  for value in (None, 'something else'):
+second_authority = dict(authority_attr)
+second_authority[attr] = value
+self.assertNotEqual(stem.directory.Authority(**authority_attr), 
stem.directory.Authority(**second_authority))
diff --git a/test/unit/directory/fallback.py b/test/unit/directory/fallback.py
index c95d74b7..cd857b9f 100644
--- a/test/unit/directory/fallback.py
+++ b/test/unit/directory/fallback.py
@@ -65,6 +65,30 @@ FALLBACK_ENTRY = b"""\
 
 
 class TestFallback(unittest.TestCase):
+  def test_equality(self):
+fallback_attr = {
+  'address': '5.9.110.236',
+  'or_port': 9001,
+  'dir_port': 9030,
+  'fingerprint': '0756B7CD4DFC8182BE23143FAC0642F515182CEB',
+  'nickname': 'rueckgrat',
+  'has_extrainfo': True,
+  'orport_v6': ('2a01:4f8:162:51e2::2', 9001),
+  'header': OrderedDict((
+('type', 'fallback'),
+('version', '2.0.0'),
+('timestamp', '20170526090242'),
+  )),
+}
+
+self.assertEqual(stem.directory.Fallback(**fallback_attr), 
stem.directory.Fallback(**fallback_attr))
+
+for attr in fallback_attr:
+  for value in (None, 'something else'):
+second_fallback = dict(fallback_attr)
+second_fallback[attr] = value
+self.assertNotEqual(stem.directory.Fallback(**fallback_attr), 
stem.directory.Fallback(**second_fallback))
+
   def test_from_cache(self):
 # quick sanity test that we can load cached content
 fallback_directories = stem.directory.Fallback.from_cache()



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Remove usage of directory aliases

2018-05-08 Thread atagar
commit 0a583e678ac9b359685e24e3299337d2f8ced99f
Author: Damian Johnson 
Date:   Mon May 7 10:07:00 2018 -0700

Remove usage of directory aliases

We provide backward compatablitiy, but we ourselves should reference the new
module.
---
 docs/_static/example/compare_flags.py  | 15 ++-
 docs/_static/example/votes_by_bandwidth_authorities.py |  7 ---
 stem/descriptor/remote.py  |  8 
 test/integ/descriptor/remote.py|  9 +
 test/unit/descriptor/remote.py |  4 
 test/unit/tutorial_examples.py | 12 ++--
 6 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/docs/_static/example/compare_flags.py 
b/docs/_static/example/compare_flags.py
index df317a89..1efb1d2c 100644
--- a/docs/_static/example/compare_flags.py
+++ b/docs/_static/example/compare_flags.py
@@ -1,16 +1,21 @@
-from collections import OrderedDict
-from stem.descriptor import DocumentHandler, remote
+import collections
+
+import stem.descriptor
+import stem.descriptor.remote
+import stem.directory
 
 # Query all authority votes asynchronously.
 
-downloader = 
remote.DescriptorDownloader(document_handler=DocumentHandler.DOCUMENT)
+downloader = stem.descriptor.remote.DescriptorDownloader(
+  document_handler = stem.descriptor.DocumentHandler.DOCUMENT,
+)
 
 # An ordered dictionary ensures queries are finished in the order they were
 # added.
 
-queries = OrderedDict()
+queries = collections.OrderedDict()
 
-for name, authority in remote.get_authorities().items():
+for name, authority in stem.directory.Authority.from_cache().items():
   if authority.v3ident is None:
 continue  # authority doesn't vote if it lacks a v3ident
 
diff --git a/docs/_static/example/votes_by_bandwidth_authorities.py 
b/docs/_static/example/votes_by_bandwidth_authorities.py
index f6816b74..9504bd94 100644
--- a/docs/_static/example/votes_by_bandwidth_authorities.py
+++ b/docs/_static/example/votes_by_bandwidth_authorities.py
@@ -1,11 +1,12 @@
-from stem.descriptor import remote
+import stem.descriptor.remote
+import stem.directory
 
 # request votes from all the bandwidth authorities
 
 queries = {}
-downloader = remote.DescriptorDownloader()
+downloader = stem.descriptor.remote.DescriptorDownloader()
 
-for authority in remote.get_authorities().values():
+for authority in stem.directory.Authority.from_cache().values():
   if authority.is_bandwidth_authority:
 queries[authority.nickname] = downloader.query(
   '/tor/status-vote/current/authority',
diff --git a/stem/descriptor/remote.py b/stem/descriptor/remote.py
index bc23063a..a8be9280 100644
--- a/stem/descriptor/remote.py
+++ b/stem/descriptor/remote.py
@@ -496,7 +496,7 @@ class Query(object):
 """
 
 if use_authority or not self.endpoints:
-  picked = random.choice([auth for auth in get_authorities().values() if 
auth.nickname not in ('tor26', 'Bifroest')])
+  picked = random.choice([auth for auth in 
stem.directory.Authority.from_cache().values() if auth.nickname not in 
('tor26', 'Bifroest')])
   return stem.DirPort(picked.address, picked.dir_port)
 else:
   return random.choice(self.endpoints)
@@ -547,7 +547,7 @@ class DescriptorDownloader(object):
   def __init__(self, use_mirrors = False, **default_args):
 self._default_args = default_args
 
-directories = list(get_authorities().values())
+directories = list(stem.directory.Authority.from_cache().values())
 self._endpoints = [(directory.address, directory.dir_port) for directory 
in directories]
 
 if use_mirrors:
@@ -569,7 +569,7 @@ class DescriptorDownloader(object):
 :raises: **Exception** if unable to determine the directory mirrors
 """
 
-directories = get_authorities().values()
+directories = stem.directory.Authority.from_cache().values()
 new_endpoints = set([(directory.address, directory.dir_port) for directory 
in directories])
 
 consensus = list(self.get_consensus(document_handler = 
stem.descriptor.DocumentHandler.DOCUMENT).run())[0]
@@ -735,7 +735,7 @@ class DescriptorDownloader(object):
 """
 Provides the present vote for a given directory authority.
 
-:param stem.descriptor.remote.DirectoryAuthority authority: authority for 
which to retrieve a vote for
+:param stem.directory.Authority authority: authority for which to retrieve 
a vote for
 :param query_args: additional arguments for the
   :class:`~stem.descriptor.remote.Query` constructor
 
diff --git a/test/integ/descriptor/remote.py b/test/integ/descriptor/remote.py
index 0305d069..c4e4f699 100644
--- a/test/integ/descriptor/remote.py
+++ b/test/integ/descriptor/remote.py
@@ -11,6 +11,7 @@ import stem.descriptor.networkstatus
 import stem.descriptor.remote
 import stem.descriptor.router_status_entry
 import stem.descriptor.server_descriptor
+import stem.directory
 import test.require
 
 

[tor-commits] [stem/master] Add orport_v6 to the Authority class

2018-05-08 Thread atagar
commit e554de7373e017c788ba411dd850d2e7c518390a
Author: Damian Johnson 
Date:   Tue May 8 12:01:34 2018 -0700

Add orport_v6 to the Authority class

Moving the orport_v6 attribute from Fallback up to the parent Directory 
class,
effectively adding it to directory authorities. This was added to tor's 
backed
in information.
---
 docs/change_log.rst  |  1 +
 stem/directory.py| 51 +---
 test/unit/directory/authority.py |  2 ++
 3 files changed, 30 insertions(+), 24 deletions(-)

diff --git a/docs/change_log.rst b/docs/change_log.rst
index 67359a95..3836b8ad 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -60,6 +60,7 @@ The following are only available within Stem's `git repository
   * Moved the Directory classes into their own `stem.directory 
`_ module
   * Added :func:`~stem.descriptor.remote.Directory.from_cache` and 
:func:`~stem.descriptor.remote.Directory.from_remote` to the 
:class:`~stem.descriptor.remote.DirectoryAuthority` subclass
   * `Fallback directory v2 support 
`_, 
which adds *nickname* and *extrainfo*
+  * Added the *orport_v6* attribute to the :class:`~stem.directory.Authority` 
class
   * Added server descriptor's new is_hidden_service_dir attribute
   * Don't retry downloading descriptors when we've timed out
   * Don't download from tor26 and Bifroest, which are authorities that 
frequently timeout
diff --git a/stem/directory.py b/stem/directory.py
index acd24a80..b638a354 100644
--- a/stem/directory.py
+++ b/stem/directory.py
@@ -91,17 +91,16 @@ class Directory(object):
   names, whereas fallbacks vary more and don't necessarily have a nickname to
   key off of.
 
-  .. versionchanged:: 1.3.0
- Moved nickname from subclasses to this base class.
-
   :var str address: IPv4 address of the directory
   :var int or_port: port on which the relay services relay traffic
   :var int dir_port: port on which directory information is available
   :var str fingerprint: relay fingerprint
   :var str nickname: relay nickname
+  :var str orport_v6: **(address, port)** tuple for the directory's IPv6
+ORPort, or **None** if it doesn't have one
   """
 
-  def __init__(self, address, or_port, dir_port, fingerprint, nickname):
+  def __init__(self, address, or_port, dir_port, fingerprint, nickname, 
orport_v6):
 identifier = '%s (%s)' % (fingerprint, nickname) if nickname else 
fingerprint
 
 if not connection.is_valid_ipv4_address(address):
@@ -115,11 +114,20 @@ class Directory(object):
 elif nickname and not tor_tools.is_valid_nickname(nickname):
   raise ValueError('%s has an invalid nickname: %s' % (fingerprint, 
nickname))
 
+if orport_v6:
+  if not isinstance(orport_v6, tuple) or len(orport_v6) != 2:
+raise ValueError('%s orport_v6 should be a two value tuple: %s' % 
(identifier, str(orport_v6)))
+  elif not connection.is_valid_ipv6_address(orport_v6[0]):
+raise ValueError('%s has an invalid IPv6 address: %s' % (identifier, 
orport_v6[0]))
+  elif not connection.is_valid_port(orport_v6[1]):
+raise ValueError('%s has an invalid IPv6 port: %s' % (identifier, 
orport_v6[1]))
+
 self.address = address
 self.or_port = int(or_port)
 self.dir_port = int(dir_port)
 self.fingerprint = fingerprint
 self.nickname = nickname
+self.orport_v6 = (orport_v6[0], int(orport_v6[1])) if orport_v6 else None
 
   @staticmethod
   def from_cache():
@@ -169,7 +177,7 @@ class Directory(object):
 raise NotImplementedError('Unsupported Operation: this should be 
implemented by the Directory subclass')
 
   def __hash__(self):
-return _hash_attr(self, 'address', 'or_port', 'dir_port', 'fingerprint', 
'nickname')
+return _hash_attr(self, 'address', 'or_port', 'dir_port', 'fingerprint', 
'nickname', 'orport_v6')
 
   def __eq__(self, other):
 return hash(self) == hash(other) if isinstance(other, Directory) else False
@@ -187,6 +195,9 @@ class Authority(Directory):
   .. versionchanged:: 1.3.0
  Added the is_bandwidth_authority attribute.
 
+  .. versionchanged:: 1.7.0
+ Added the orport_v6 attribute.
+
   .. deprecated:: 1.7.0
  The is_bandwidth_authority attribute is deprecated and will be removed in
  the future.
@@ -194,8 +205,8 @@ class Authority(Directory):
   :var str v3ident: identity key fingerprint used to sign votes and consensus
   """
 
-  def __init__(self, address = None, or_port = None, dir_port = None, 
fingerprint = None, nickname = None, v3ident = None, is_bandwidth_authority = 
False):
-super(Authority, self).__init__(address, or_port, dir_port, fingerprint, 
nickname)
+  def __init__(self, address = None, or_port = None, dir_port = None, 
fingerprint = None, nickname = None, orport_v6 = None, v3ident = None, 
is_bandwidth_authority = False):
+super(Authority, self).__init__(address, 

[tor-commits] [stem/master] Move helper functions to end of remote module

2018-05-08 Thread atagar
commit df2df79855ff92d3452fa5841f18397895424861
Author: Damian Johnson 
Date:   Sat May 5 13:46:53 2018 -0700

Move helper functions to end of remote module

Generally I've kept with the ordering of: functions, classes, helpers. This 
way
the publicly accessible stuff is first.
---
 stem/descriptor/remote.py | 304 +++---
 1 file changed, 152 insertions(+), 152 deletions(-)

diff --git a/stem/descriptor/remote.py b/stem/descriptor/remote.py
index 1b6a7ea6..bc23063a 100644
--- a/stem/descriptor/remote.py
+++ b/stem/descriptor/remote.py
@@ -202,158 +202,6 @@ def get_consensus(authority_v3ident = None, 
microdescriptor = False, **query_arg
   return get_instance().get_consensus(authority_v3ident, microdescriptor, 
**query_args)
 
 
-def _download_from_orport(endpoint, compression, resource):
-  """
-  Downloads descriptors from the given orport. Payload is just like an http
-  response (headers and all)...
-
-  ::
-
-HTTP/1.0 200 OK
-Date: Mon, 23 Apr 2018 18:43:47 GMT
-Content-Type: text/plain
-X-Your-Address-Is: 216.161.254.25
-Content-Encoding: identity
-Expires: Wed, 25 Apr 2018 18:43:47 GMT
-
-router dannenberg 193.23.244.244 443 0 80
-identity-ed25519
-... rest of the descriptor content...
-
-  :param stem.ORPort endpoint: endpoint to download from
-  :param list compression: compression methods for the request
-  :param str resource: descriptor resource to download
-
-  :returns: two value tuple of the form (data, reply_headers)
-
-  :raises:
-* :class:`stem.ProtocolError` if not a valid descriptor response
-* :class:`stem.SocketError` if unable to establish a connection
-  """
-
-  link_protocols = endpoint.link_protocols if endpoint.link_protocols else [3]
-
-  with stem.client.Relay.connect(endpoint.address, endpoint.port, 
link_protocols) as relay:
-with relay.create_circuit() as circ:
-  request = '\r\n'.join((
-'GET %s HTTP/1.0' % resource,
-'Accept-Encoding: %s' % ', '.join(compression),
-'User-Agent: Stem/%s' % stem.__version__,
-  )) + '\r\n\r\n'
-
-  circ.send('RELAY_BEGIN_DIR', stream_id = 1)
-  response = b''.join([cell.data for cell in circ.send('RELAY_DATA', 
request, stream_id = 1)])
-  first_line, data = response.split(b'\r\n', 1)
-  header_data, data = data.split(b'\r\n\r\n', 1)
-
-  if first_line != b'HTTP/1.0 200 OK':
-raise stem.ProtocolError("Response should begin with HTTP success, but 
was '%s'" % first_line)
-
-  headers = {}
-
-  for line in str_tools._to_unicode(header_data).splitlines():
-if ': ' not in line:
-  raise stem.ProtocolError("'%s' is not a HTTP header:\n\n%s" % line)
-
-key, value = line.split(': ', 1)
-headers[key] = value
-
-  return _decompress(data, headers.get('Content-Encoding')), headers
-
-
-def _download_from_dirport(url, compression, timeout):
-  """
-  Downloads descriptors from the given url.
-
-  :param str url: dirport url from which to download from
-  :param list compression: compression methods for the request
-  :param float timeout: duration before we'll time out our request
-
-  :returns: two value tuple of the form (data, reply_headers)
-
-  :raises:
-* **socket.timeout** if our request timed out
-* **urllib2.URLError** for most request failures
-  """
-
-  response = urllib.urlopen(
-urllib.Request(
-  url,
-  headers = {
-'Accept-Encoding': ', '.join(compression),
-'User-Agent': 'Stem/%s' % stem.__version__,
-  }
-),
-timeout = timeout,
-  )
-
-  return _decompress(response.read(), 
response.headers.get('Content-Encoding')), response.headers
-
-
-def _decompress(data, encoding):
-  """
-  Decompresses descriptor data.
-
-  Tor doesn't include compression headers. As such when using gzip we
-  need to include '32' for automatic header detection...
-
-
https://stackoverflow.com/questions/3122145/zlib-error-error-3-while-decompressing-incorrect-header-check/22310760#22310760
-
-  ... and with zstd we need to use the streaming API.
-
-  :param bytes data: data we received
-  :param str encoding: 'Content-Encoding' header of the response
-
-  :raises:
-* **ValueError** if encoding is unrecognized
-* **ImportError** if missing the decompression module
-  """
-
-  if encoding == Compression.PLAINTEXT:
-return data.strip()
-  elif encoding in (Compression.GZIP, 'deflate'):
-return zlib.decompress(data, zlib.MAX_WBITS | 32).strip()
-  elif encoding == Compression.ZSTD:
-if not stem.prereq.is_zstd_available():
-  raise ImportError('Decompressing zstd data requires 
https://pypi.python.org/pypi/zstandard')
-
-import zstd
-output_buffer = io.BytesIO()
-
-with zstd.ZstdDecompressor().write_to(output_buffer) as decompressor:
-  decompressor.write(data)
-
-return output_buffer.getvalue().strip()
-  elif encoding == Compression.LZMA:
-  

[tor-commits] [stem/master] Move authority docs into module header

2018-05-08 Thread atagar
commit d99d6470ccc50eeefec056f2305cdacd05e07eef
Author: Damian Johnson 
Date:   Sat May 5 14:44:57 2018 -0700

Move authority docs into module header

This more expansive explanation of how tor works belongs in our module docs,
not this particular class.
---
 stem/directory.py | 62 +++
 1 file changed, 30 insertions(+), 32 deletions(-)

diff --git a/stem/directory.py b/stem/directory.py
index 4190e885..2982f4d0 100644
--- a/stem/directory.py
+++ b/stem/directory.py
@@ -2,16 +2,38 @@
 # See LICENSE for licensing information
 
 """
-Directories with Tor descriptor information.
+Directories with `tor descriptor information
+<../tutorials/mirror_mirror_on_the_wall.html>`_. At a very high level tor works
+as follows...
+
+1. Volunteer starts a new tor relay, during which it sends a `server
+   descriptor `_ to each of the directory
+   authorities.
+
+2. Each hour the directory authorities make a `vote
+   `_  that says who they think the active
+   relays are in the network and some attributes about them.
+
+3. The directory authorities send each other their votes, and compile that
+   into the `consensus `_. This document is very
+   similar to the votes, the only difference being that the majority of the
+   authorities agree upon and sign this document. The idividual relay entries
+   in the vote or consensus is called `router status entries
+   `_.
+
+4. Tor clients (people using the service) download the consensus from an
+   authority, fallback, or other mirror to determine who the active relays in
+   the network are. They then use this to construct circuits and use the
+   network.
 
 ::
 
-  Directory - Relay we can retrieve directory information from
-| |- from_cache - Provides fallback directories cached with Stem.
-| +- from_remote - Retrieves fallback directories remotely from tor's 
latest commit.
+  Directory - Relay we can retrieve descriptor information from
+| |- from_cache - Provides cached information bundled with Stem.
+| +- from_remote - Downloads the latest directory information from tor.
 |
-|- Authority - Information about a tor directory authority
-+- Fallback - Directory mirror tor uses when authories are unavailable
+|- Authority - Tor directory authority
++- Fallback - Mirrors that can be used instead of the authorities
 
 .. versionadded:: 1.7.0
 """
@@ -149,28 +171,6 @@ class Authority(Directory):
   `_
   that enumerates the other relays within the network.
 
-  At a very high level tor works as follows...
-
-  1. A volunteer starts up a new tor relay, during which it sends a `server
- descriptor `_ to each of the directory
- authorities.
-
-  2. Each hour the directory authorities make a `vote `_
- that says who they think the active relays are in the network and some
- attributes about them.
-
-  3. The directory authorities send each other their votes, and compile that
- into the `consensus `_. This document is very similar
- to the votes, the only difference being that the majority of the
- authorities agree upon and sign this document. The idividual relay entries
- in the vote or consensus is called `router status entries
- `_.
-
-  4. Tor clients (people using the service) download the consensus from one of
- the authorities or a mirror to determine the active relays within the
- network. They in turn use this to construct their circuits and use the
- network.
-
   .. versionchanged:: 1.3.0
  Added the is_bandwidth_authority attribute.
 
@@ -319,14 +319,12 @@ class Fallback(Directory):
   ::
 
 import time
-from stem.descriptor.remote import DescriptorDownloader
+from stem.descriptor.remote import get_consensus
 from stem.directory import Fallback
 
-downloader = DescriptorDownloader()
-
 for fallback in Fallback.from_cache().values():
   start = time.time()
-  downloader.get_consensus(endpoints = [(fallback.address, 
fallback.dir_port)]).run()
+  get_consensus(endpoints = [(fallback.address, fallback.dir_port)]).run()
   print('Downloading the consensus took %0.2f from %s' % (time.time() - 
start, fallback.fingerprint))
 
   ::



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Move zstd and lzma checks to prereq module

2018-05-08 Thread atagar
commit bb260c0ab9bd7d8fad08657b21a36a186e7a5fe0
Author: Damian Johnson 
Date:   Sat May 5 13:41:36 2018 -0700

Move zstd and lzma checks to prereq module

This is the spot where we do these prereq checks. Yay, remote module's 
finally
under the 1k line threshold.
---
 stem/descriptor/remote.py  | 38 +--
 stem/prereq.py | 51 --
 test/settings.cfg  |  1 +
 test/unit/descriptor/remote.py | 12 +-
 4 files changed, 62 insertions(+), 40 deletions(-)

diff --git a/stem/descriptor/remote.py b/stem/descriptor/remote.py
index 301e89d9..1b6a7ea6 100644
--- a/stem/descriptor/remote.py
+++ b/stem/descriptor/remote.py
@@ -113,29 +113,6 @@ try:
 except ImportError:
   import urllib2 as urllib
 
-try:
-  # added in python 3.3
-  import lzma
-  LZMA_SUPPORTED = True
-except ImportError:
-  LZMA_SUPPORTED = False
-
-try:
-  # We use the suggested python zstd library...
-  #
-  #   https://pypi.python.org/pypi/zstandard
-  #
-  # Unfortunately this installs as a zstd module which can be confused with...
-  #
-  #   https://pypi.python.org/pypi/zstd
-  #
-  # As such checking for the specific decompression class we'll need.
-
-  import zstd
-  ZSTD_SUPPORTED = hasattr(zstd, 'ZstdDecompressor')
-except ImportError:
-  ZSTD_SUPPORTED = False
-
 Compression = stem.util.enum.Enum(
   ('PLAINTEXT', 'identity'),
   ('GZIP', 'gzip'),  # can also be 'deflate'
@@ -143,9 +120,6 @@ Compression = stem.util.enum.Enum(
   ('LZMA', 'x-tor-lzma'),
 )
 
-ZSTD_UNAVAILABLE_MSG = 'ZSTD compression requires the zstandard module 
(https://pypi.python.org/pypi/zstandard)'
-LZMA_UNAVAILABLE_MSG = 'LZMA compression requires the lzma module 
(https://docs.python.org/3/library/lzma.html)'
-
 # Tor has a limited number of descriptors we can fetch explicitly by their
 # fingerprint or hashes due to a limit on the url length by squid proxies.
 
@@ -340,9 +314,10 @@ def _decompress(data, encoding):
   elif encoding in (Compression.GZIP, 'deflate'):
 return zlib.decompress(data, zlib.MAX_WBITS | 32).strip()
   elif encoding == Compression.ZSTD:
-if not ZSTD_SUPPORTED:
+if not stem.prereq.is_zstd_available():
   raise ImportError('Decompressing zstd data requires 
https://pypi.python.org/pypi/zstandard')
 
+import zstd
 output_buffer = io.BytesIO()
 
 with zstd.ZstdDecompressor().write_to(output_buffer) as decompressor:
@@ -350,9 +325,10 @@ def _decompress(data, encoding):
 
 return output_buffer.getvalue().strip()
   elif encoding == Compression.LZMA:
-if not LZMA_SUPPORTED:
+if not stem.prereq.is_lzma_available():
   raise ImportError('Decompressing lzma data requires 
https://docs.python.org/3/library/lzma.html')
 
+import lzma
 return lzma.decompress(data).strip()
   else:
 raise ValueError("'%s' isn't a recognized type of encoding" % encoding)
@@ -528,12 +504,10 @@ class Query(object):
   if isinstance(compression, str):
 compression = [compression]  # caller provided only a single option
 
-  if Compression.ZSTD in compression and not ZSTD_SUPPORTED:
-log.log_once('stem.descriptor.remote.zstd_unavailable', log.INFO, 
ZSTD_UNAVAILABLE_MSG)
+  if Compression.ZSTD in compression and not 
stem.prereq.is_zstd_available():
 compression.remove(Compression.ZSTD)
 
-  if Compression.LZMA in compression and not LZMA_SUPPORTED:
-log.log_once('stem.descriptor.remote.lzma_unavailable', log.INFO, 
LZMA_UNAVAILABLE_MSG)
+  if Compression.LZMA in compression and not 
stem.prereq.is_lzma_available():
 compression.remove(Compression.LZMA)
 
   if not compression:
diff --git a/stem/prereq.py b/stem/prereq.py
index 16437c23..6e230007 100644
--- a/stem/prereq.py
+++ b/stem/prereq.py
@@ -16,6 +16,8 @@ Checks for stem dependencies. We require python 2.6 or 
greater (including the
   is_python_3 - checks if python 3.0 or later is available
   is_sqlite_available - checks if the sqlite3 module is available
   is_crypto_available - checks if the cryptography module is available
+  is_zstd_available - checks if the zstd module is available
+  is_lzma_available - checks if the lzma module is available
   is_mock_available - checks if the mock module is available
 """
 
@@ -29,6 +31,8 @@ except ImportError:
   from stem.util.lru_cache import lru_cache
 
 CRYPTO_UNAVAILABLE = "Unable to import the cryptography module. Because of 
this we'll be unable to verify descriptor signature integrity. You can get 
cryptography from: https://pypi.python.org/pypi/cryptography;
+ZSTD_UNAVAILABLE = 'ZSTD compression requires the zstandard module 
(https://pypi.python.org/pypi/zstandard)'
+LZMA_UNAVAILABLE = 'LZMA compression requires the lzma module 
(https://docs.python.org/3/library/lzma.html)'
 PYNACL_UNAVAILABLE = "Unable to import the pynacl module. Because of this 
we'll be unable to verify descriptor ed25519 certificate 

[tor-commits] [stem/master] Move Directory into its own module

2018-05-08 Thread atagar
commit 609a411d05fc3288efd27d419fd478906e08bc34
Author: Damian Johnson 
Date:   Sat May 5 12:57:58 2018 -0700

Move Directory into its own module

Directory authorities started as a small, simple constant so it made sense 
to
co-locate them in the remote module (the sole spot they were used). But 
they've
grown. With the addition of fallback directories and from_remote() parsers
they're now the bulk of the remote module and way past the point where they
deserve their own module.

Adding a stem.directory module with aliases for backward compatability. Also
shortening the names. With this the module is a *lot* nicer to use. For
instance to list the authorities we're going from...

  for authority in stem.descriptor.remote.DirectoryAuthority.from_cache():
print(authority.nickname)

... to...

  for authority in stem.directory.Authority.from_cache():
print(authority.nickname)

Quite a few other improvements I'd like to follow this up with, but starting
with just a simple move.
---
 docs/api/directory.rst |   5 +
 docs/change_log.rst|   9 +-
 setup.py   |   3 +-
 stem/__init__.py   |   1 +
 stem/descriptor/remote.py  | 710 +---
 stem/directory.py  | 725 +
 stem/{descriptor => }/fallback_directories.cfg |   0
 test/unit/tutorial_examples.py |   2 +-
 8 files changed, 746 insertions(+), 709 deletions(-)

diff --git a/docs/api/directory.rst b/docs/api/directory.rst
new file mode 100644
index ..befd1d59
--- /dev/null
+++ b/docs/api/directory.rst
@@ -0,0 +1,5 @@
+Directory
+=
+
+.. automodule:: stem.directory
+
diff --git a/docs/change_log.rst b/docs/change_log.rst
index d5505821..67359a95 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -57,15 +57,16 @@ The following are only available within Stem's `git 
repository
 
   * `stem.descriptor.remote `_ can now download 
from relay ORPorts
   * Zstd and lzma compression support (:spec:`1cb56af`)
-  * Added :func:`~stem.descriptor.remote.Directory.from_cache` and 
:func:`~stem.descriptor.remote.Directory.from_remote` to the 
:class:`~stem.descriptor.remote.DirectoryAuthority` subclass.
+  * Moved the Directory classes into their own `stem.directory 
`_ module
+  * Added :func:`~stem.descriptor.remote.Directory.from_cache` and 
:func:`~stem.descriptor.remote.Directory.from_remote` to the 
:class:`~stem.descriptor.remote.DirectoryAuthority` subclass
   * `Fallback directory v2 support 
`_, 
which adds *nickname* and *extrainfo*
   * Added server descriptor's new is_hidden_service_dir attribute
   * Don't retry downloading descriptors when we've timed out
-  * Don't download from tor26 and Bifroest, which are authorities that 
frequently timeout.
-  * `stem.descriptor.remote `_  now consistently 
defaults **fall_back_to_authority** to false.
+  * Don't download from tor26 and Bifroest, which are authorities that 
frequently timeout
+  * `stem.descriptor.remote `_  now consistently 
defaults **fall_back_to_authority** to false
   * Added :func:`~stem.descriptor.remote.their_server_descriptor`
   * Added the reply_headers attribute to :class:`~stem.descriptor.remote.Query`
-  * Supplying a User-Agent when downloading descriptors.
+  * Supplying a User-Agent when downloading descriptors
   * Reduced maximum descriptors fetched by the remote module to match tor's 
new limit (:trac:`24743`)
   * Consensus **shared_randomness_*_reveal_count** attributes undocumented, 
and unavailable if retrieved before their corresponding 
shared_randomness_*_value attribute (:trac:`25046`)
   * Allow 'proto' line to have blank values (:spec:`a8455f4`)
diff --git a/setup.py b/setup.py
index 87a766b5..9e200bf1 100644
--- a/setup.py
+++ b/setup.py
@@ -106,8 +106,7 @@ try:
 keywords = 'tor onion controller',
 scripts = ['tor-prompt'],
 package_data = {
-  'stem': ['cached_tor_manual.sqlite', 'settings.cfg'],
-  'stem.descriptor': ['fallback_directories.cfg'],
+  'stem': ['cached_tor_manual.sqlite', 'fallback_directories.cfg', 
'settings.cfg'],
   'stem.interpreter': ['settings.cfg'],
   'stem.util': ['ports.cfg'],
 }, classifiers = [
diff --git a/stem/__init__.py b/stem/__init__.py
index c7432d86..0104d3b2 100644
--- a/stem/__init__.py
+++ b/stem/__init__.py
@@ -492,6 +492,7 @@ __all__ = [
   'util',
   'connection',
   'control',
+  'directory',
   'exit_policy',
   'prereq',
   'process',
diff --git a/stem/descriptor/remote.py b/stem/descriptor/remote.py
index e0b4c21d..301e89d9 100644
--- a/stem/descriptor/remote.py
+++ b/stem/descriptor/remote.py
@@ -50,13 +50,6 @@ content. For example...
 |- 

[tor-commits] [stem/master] Double checking fields in equality check

2018-05-08 Thread atagar
commit 33b20dcbd4b1f0ddc84085766dfbcfffc5e5e18a
Author: Damian Johnson 
Date:   Sun May 6 12:05:51 2018 -0700

Double checking fields in equality check

Our Directory class hashed its attributes, then the subclasses hashed some 
of
them again. Not harmful, but also not necessary.
---
 stem/directory.py | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/stem/directory.py b/stem/directory.py
index 2982f4d0..7b78696a 100644
--- a/stem/directory.py
+++ b/stem/directory.py
@@ -113,7 +113,7 @@ class Directory(object):
 """
 Provides cached Tor directory information. This information is hardcoded
 into Tor and occasionally changes, so the information this provides might
-not necessarily match your version of tor.
+not necessarily match the latest version of tor.
 
 .. versionadded:: 1.5.0
 
@@ -156,7 +156,7 @@ class Directory(object):
 raise NotImplementedError('Unsupported Operation: this should be 
implemented by the Directory subclass')
 
   def __hash__(self):
-return _hash_attr(self, 'address', 'or_port', 'dir_port', 'fingerprint')
+return _hash_attr(self, 'address', 'or_port', 'dir_port', 'fingerprint', 
'nickname')
 
   def __eq__(self, other):
 return hash(self) == hash(other) if isinstance(other, Directory) else False
@@ -299,7 +299,7 @@ class Authority(Directory):
 return section_lines
 
   def __hash__(self):
-return _hash_attr(self, 'nickname', 'v3ident', 'is_bandwidth_authority', 
parent = Directory)
+return _hash_attr(self, 'v3ident', 'is_bandwidth_authority', parent = 
Directory)
 
   def __eq__(self, other):
 return hash(self) == hash(other) if isinstance(other, Authority) else False
@@ -574,7 +574,7 @@ class Fallback(Directory):
 conf.save(path)
 
   def __hash__(self):
-return _hash_attr(self, 'address', 'or_port', 'dir_port', 'fingerprint', 
'nickname', 'has_extrainfo', 'orport_v6', 'header', parent = Directory)
+return _hash_attr(self, 'has_extrainfo', 'orport_v6', 'header', parent = 
Directory)
 
   def __eq__(self, other):
 return hash(self) == hash(other) if isinstance(other, Fallback) else False



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Rename cache files

2018-05-08 Thread atagar
commit 972f4a1b773b9b4bfb9a6127f1d7184e3cade5be
Author: Damian Johnson 
Date:   Sat May 5 13:11:25 2018 -0700

Rename cache files

Shorter and more consistant names.
---
 setup.py|   2 +-
 stem/{fallback_directories.cfg => cached_fallbacks.cfg} |   0
 stem/{cached_tor_manual.sqlite => cached_manual.sqlite} | Bin
 stem/directory.py   |   2 +-
 stem/manual.py  |   2 +-
 test/unit/installation.py   |   3 +--
 6 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/setup.py b/setup.py
index 9e200bf1..1d674e13 100644
--- a/setup.py
+++ b/setup.py
@@ -106,7 +106,7 @@ try:
 keywords = 'tor onion controller',
 scripts = ['tor-prompt'],
 package_data = {
-  'stem': ['cached_tor_manual.sqlite', 'fallback_directories.cfg', 
'settings.cfg'],
+  'stem': ['cached_fallbacks.cfg', 'cached_manual.sqlite', 'settings.cfg'],
   'stem.interpreter': ['settings.cfg'],
   'stem.util': ['ports.cfg'],
 }, classifiers = [
diff --git a/stem/fallback_directories.cfg b/stem/cached_fallbacks.cfg
similarity index 100%
rename from stem/fallback_directories.cfg
rename to stem/cached_fallbacks.cfg
diff --git a/stem/cached_tor_manual.sqlite b/stem/cached_manual.sqlite
similarity index 100%
rename from stem/cached_tor_manual.sqlite
rename to stem/cached_manual.sqlite
diff --git a/stem/directory.py b/stem/directory.py
index b7bc201f..4190e885 100644
--- a/stem/directory.py
+++ b/stem/directory.py
@@ -38,7 +38,7 @@ except ImportError:
 
 GITWEB_AUTHORITY_URL = 
'https://gitweb.torproject.org/tor.git/plain/src/or/auth_dirs.inc'
 GITWEB_FALLBACK_URL = 
'https://gitweb.torproject.org/tor.git/plain/src/or/fallback_dirs.inc'
-CACHE_PATH = os.path.join(os.path.dirname(__file__), 
'fallback_directories.cfg')
+CACHE_PATH = os.path.join(os.path.dirname(__file__), 'cached_fallbacks.cfg')
 
 AUTHORITY_NAME = re.compile('"(\S+) orport=(\d+) .*"')
 AUTHORITY_V3IDENT = re.compile('"v3ident=([\dA-F]{40}) "')
diff --git a/stem/manual.py b/stem/manual.py
index 3d734026..f8e7ea96 100644
--- a/stem/manual.py
+++ b/stem/manual.py
@@ -81,7 +81,7 @@ except ImportError:
 
 Category = stem.util.enum.Enum('GENERAL', 'CLIENT', 'RELAY', 'DIRECTORY', 
'AUTHORITY', 'HIDDEN_SERVICE', 'DENIAL_OF_SERVICE', 'TESTING', 'UNKNOWN')
 GITWEB_MANUAL_URL = 'https://gitweb.torproject.org/tor.git/plain/doc/tor.1.txt'
-CACHE_PATH = os.path.join(os.path.dirname(__file__), 
'cached_tor_manual.sqlite')
+CACHE_PATH = os.path.join(os.path.dirname(__file__), 'cached_manual.sqlite')
 DATABASE = None  # cache database connections
 HAS_ENCODING_ARG = not stem.util.system.is_mac() and not 
stem.util.system.is_bsd() and not stem.util.system.is_slackware()
 
diff --git a/test/unit/installation.py b/test/unit/installation.py
index 15d9fe85..feb52d89 100644
--- a/test/unit/installation.py
+++ b/test/unit/installation.py
@@ -54,8 +54,7 @@ class TestInstallation(unittest.TestCase):
 # Checking that we have all non-source files. Data looks like...
 #
 #   package_data = {
-# 'stem': ['cached_tor_manual.cfg', 'settings.cfg'],
-# 'stem.descriptor': ['fallback_directories.cfg'],
+# 'stem': ['cached_fallbacks.cfg', 'cached_manual.cfg', 
'settings.cfg'],
 #   },
 
 package_data = {}



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [stem/master] Separate fallback unit tests

2018-05-08 Thread atagar
commit cf2b82b06688b4355a848029592ccdbea7fb3ebd
Author: Damian Johnson 
Date:   Sat May 5 14:30:57 2018 -0700

Separate fallback unit tests

Now that directories have their own module we can separate the fallback unit
tests into their own module. We should add similar tests for authorities.
---
 test/settings.cfg   |   1 +
 test/unit/__init__.py   |   1 +
 test/unit/descriptor/remote.py  | 176 
 test/unit/directory/__init__.py |   7 ++
 test/unit/directory/fallback.py | 194 
 5 files changed, 203 insertions(+), 176 deletions(-)

diff --git a/test/settings.cfg b/test/settings.cfg
index 60224463..2206c7e7 100644
--- a/test/settings.cfg
+++ b/test/settings.cfg
@@ -220,6 +220,7 @@ test.unit_tests
 |test.unit.endpoint.TestEndpoint
 |test.unit.version.TestVersion
 |test.unit.manual.TestManual
+|test.unit.directory.fallback.TestFallback
 |test.unit.tutorial.TestTutorial
 |test.unit.tutorial_examples.TestTutorialExamples
 |test.unit.response.add_onion.TestAddOnionResponse
diff --git a/test/unit/__init__.py b/test/unit/__init__.py
index 34fcbb19..1b16bc99 100644
--- a/test/unit/__init__.py
+++ b/test/unit/__init__.py
@@ -10,6 +10,7 @@ __all__ = [
   'connection',
   'control',
   'descriptor',
+  'directory',
   'exit_policy',
   'socket',
   'util',
diff --git a/test/unit/descriptor/remote.py b/test/unit/descriptor/remote.py
index fd831e1e..478a7143 100644
--- a/test/unit/descriptor/remote.py
+++ b/test/unit/descriptor/remote.py
@@ -5,13 +5,11 @@ Unit tests for stem.descriptor.remote.
 import io
 import re
 import socket
-import tempfile
 import time
 import unittest
 
 import stem.descriptor.remote
 import stem.prereq
-import stem.util.conf
 import stem.util.str_tools
 
 from stem.descriptor.remote import Compression
@@ -23,12 +21,6 @@ except ImportError:
   from httplib import HTTPMessage  # python2
 
 try:
-  # added in python 2.7
-  from collections import OrderedDict
-except ImportError:
-  from stem.util.ordereddict import OrderedDict
-
-try:
   # added in python 3.3
   from unittest.mock import patch, Mock, MagicMock
 except ImportError:
@@ -79,46 +71,6 @@ 
iO3EUE0AEYah2W9gdz8t+i3Dtr0zgqLS841GC/TyDKCm+MKmN8d098qnwK0NGF9q
 -END SIGNATURE-
 """
 
-FALLBACK_DIR_CONTENT = b"""\
-/* type=fallback */
-/* version=2.0.0 */
-/* timestamp=20170526090242 */
-/* = */
-/* Whitelist & blacklist excluded 1326 of 1513 candidates. */
-/* Checked IPv4 DirPorts served a consensus within 15.0s. */
-/*
-Final Count: 151 (Eligible 187, Target 392 (1963 * 0.20), Max 200)
-Excluded: 36 (Same Operator 27, Failed/Skipped Download 9, Excess 0)
-Bandwidth Range: 1.3 - 40.0 MByte/s
-*/
-/*
-Onionoo Source: details Date: 2017-05-16 07:00:00 Version: 4.0
-URL: 
https:onionoo.torproject.orgdetails?fields=fingerprint%2Cnickname%2Ccontact%2Clast_changed_address_or_port%2Cconsensus_weight%2Cadvertised_bandwidth%2Cor_addresses%2Cdir_address%2Crecommended_version%2Cflags%2Ceffective_family%2Cplatform=V2Dir=relay_seen_days=-0_seen_days=30-
-*/
-/*
-Onionoo Source: uptime Date: 2017-05-16 07:00:00 Version: 4.0
-URL: 
https:onionoo.torproject.orguptime?first_seen_days=30-=V2Dir=relay_seen_days=-0
-*/
-/* = */
-"5.9.110.236:9030 orport=9001 id=0756B7CD4DFC8182BE23143FAC0642F515182CEB"
-" ipv6=[2a01:4f8:162:51e2::2]:9001"
-/* nickname=rueckgrat */
-/* extrainfo=1 */
-/* = */
-,
-"193.171.202.146:9030 orport=9001 id=01A9258A46E97FF8B2CAC7910577862C14F2C524"
-/* nickname= */
-/* extrainfo=0 */
-/* = */
-"""
-
-FALLBACK_ENTRY = b"""\
-"5.9.110.236:9030 orport=9001 id=0756B7CD4DFC8182BE23143FAC0642F515182CEB"
-" ipv6=[2a01:4f8:162:51e2::2]:9001"
-/* nickname=rueckgrat */
-/* extrainfo=1 */
-"""
-
 HEADER = '\r\n'.join([
   'Date: Fri, 13 Apr 2018 16:35:50 GMT',
   'Content-Type: application/octet-stream',
@@ -421,131 +373,3 @@ class TestDescriptorDownloader(unittest.TestCase):
   def test_using_authorities_in_hash(self):
 # ensure our DirectoryAuthority instances can be used in hashes
 {stem.descriptor.remote.get_authorities()['moria1']: 'hello'}
-
-  def test_fallback_directories_from_cache(self):
-# quick sanity test that we can load cached content
-fallback_directories = 
stem.descriptor.remote.FallbackDirectory.from_cache()
-self.assertTrue(len(fallback_directories) > 10)
-self.assertEqual('5.39.92.199', 
fallback_directories['0BEA4A88D069753218EAAAD6D22EA87B9A1319D6'].address)
-
-  @patch(URL_OPEN, _dirport_mock(FALLBACK_DIR_CONTENT))
-  def test_fallback_directories_from_remote(self):
-fallback_directories = 
stem.descriptor.remote.FallbackDirectory.from_remote()
-header = OrderedDict((('type', 'fallback'), ('version', '2.0.0'), 
('timestamp', '20170526090242')))
-
-expected = {
-  '0756B7CD4DFC8182BE23143FAC0642F515182CEB': 
stem.descriptor.remote.FallbackDirectory(
-address = '5.9.110.236',
-or_port = 9001,
-dir_port = 9030,

[tor-commits] [tor/master] Avoid unsigned integer underflow on empty input.

2018-05-08 Thread nickm
commit a17dc0875ad0d434d9cf66d36ed23fbd69286bf3
Author: Nick Mathewson 
Date:   Mon May 7 13:56:39 2018 -0400

Avoid unsigned integer underflow on empty input.
---
 src/or/dirserv.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index d9a9b8522..e47533759 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -2641,6 +2641,12 @@ measured_bw_line_parse(measured_bw_line_t *out, const 
char *orig_line)
   int got_node_id = 0;
   char *strtok_state; /* lame sauce d'jour */
 
+  if (strlen(line) == 0) {
+log_warn(LD_DIRSERV, "Empty line in bandwidth file");
+tor_free(line);
+return -1;
+  }
+
   /* Remove end of line character, so that is not part of the token */
   if (line[strlen(line) - 1] == '\n') {
 line[strlen(line) - 1] = '\0';



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Allow bandwidth-file lines to have node_id in the last position

2018-05-08 Thread nickm
commit dbc80ad19b8a27aab557fe7930e18eef8f415133
Author: juga0 
Date:   Thu May 3 08:29:57 2018 +

Allow bandwidth-file lines to have node_id in the last position

Closes ticket 26004.
---
 src/or/dirserv.c| 6 ++
 src/test/test_dir.c | 7 +++
 2 files changed, 13 insertions(+)

diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 41c6bf3dc..d9a9b8522 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -2640,6 +2640,12 @@ measured_bw_line_parse(measured_bw_line_t *out, const 
char *orig_line)
   int got_bw = 0;
   int got_node_id = 0;
   char *strtok_state; /* lame sauce d'jour */
+
+  /* Remove end of line character, so that is not part of the token */
+  if (line[strlen(line) - 1] == '\n') {
+line[strlen(line) - 1] = '\0';
+  }
+
   cp = tor_strtok_r(cp, " \t", _state);
 
   if (!cp) {
diff --git a/src/test/test_dir.c b/src/test/test_dir.c
index cdc56acb8..b3817a092 100644
--- a/src/test/test_dir.c
+++ b/src/test/test_dir.c
@@ -1314,6 +1314,13 @@ test_dir_measured_bw_kb(void *arg)
 "bw=1024 junk=007\n",
 "misc=junk node_id=$557365204145532d32353620696e73746561642e  "
 "bw=1024 junk=007\n",
+/* check whether node_id can be at the end */
+"bw=1024 node_id=$557365204145532d32353620696e73746561642e\n",
+/* check whether node_id can be at the end and bw has something in front*/
+"foo=bar bw=1024 node_id=$557365204145532d32353620696e73746561642e\n",
+/* check whether node_id can be at the end and something in the
+ * in the middle of bw and node_id */
+"bw=1024 foo=bar node_id=$557365204145532d32353620696e73746561642e\n",
 "end"
   };
   const char *lines_fail[] = {



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Merge branch 'bug26004_029_squashed'

2018-05-08 Thread nickm
commit 3df37d7b6be4f7d6ece0cd12812595d5f91ea72f
Merge: 5edc72a45 bed3e8da9
Author: Nick Mathewson 
Date:   Tue May 8 14:26:05 2018 -0400

Merge branch 'bug26004_029_squashed'

 changes/ticket26004 |  5 +
 src/or/dirserv.c| 12 
 src/test/test_dir.c |  7 +++
 3 files changed, 24 insertions(+)

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Add a changes file for ticket 26004.

2018-05-08 Thread nickm
commit bed3e8da9cc291546da06d5a5163a3598650d545
Author: Nick Mathewson 
Date:   Mon May 7 13:57:14 2018 -0400

Add a changes file for ticket 26004.
---
 changes/ticket26004 | 5 +
 1 file changed, 5 insertions(+)

diff --git a/changes/ticket26004 b/changes/ticket26004
new file mode 100644
index 0..6b082f145
--- /dev/null
+++ b/changes/ticket26004
@@ -0,0 +1,5 @@
+  o Minor features (directory authority, forward compatibility):
+- Make the lines of the measured bandwidth file able to contain their
+  entries in any order. Previously, the node_id entry needed to come
+  first. Closes ticket 26004.
+



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Bug 25870: Prevent the creation of A - B - A vanguard sub-paths.

2018-05-08 Thread nickm
commit e34bf50604903fa54458a2e57271604440c5ad3e
Author: Mike Perry 
Date:   Tue May 1 00:59:10 2018 +

Bug 25870: Prevent the creation of A - B - A vanguard sub-paths.

These paths are illegal in Tor and relays will reject them.

We do this by using specific nodes in the exclude list (but ignore /16 and
family).
---
 src/or/circuitbuild.c | 81 ---
 1 file changed, 57 insertions(+), 24 deletions(-)

diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 75540e5d3..4bdc8a3ee 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -2445,12 +2445,56 @@ cpath_get_n_hops(crypt_path_t **head_ptr)
 #endif /* defined(TOR_UNIT_TESTS) */
 
 /**
+ * Build the exclude list for vanguard circuits.
+ *
+ * For vanguard circuits we exclude all the already chosen nodes (including
+ * the exit) from being middle hops.
+ *
+ * For vanguard circuits, we don't apply any subnet or family restrictions.
+ * This is to avoid impossible-to-build circuit paths, or just situations where
+ * our earlier guards prevent us from using most of our later ones.
+ *
+ * The alternative is building the circuit in reverse. Reverse calls to
+ * onion_extend_cpath() (ie: select outer hops first) would then have the
+ * property that you don't gain information about inner hops by observing
+ * outer ones. See https://trac.torproject.org/projects/tor/ticket/24487
+ * for this.
+ *
+ * (Note further that we still exclude the exit to prevent A - B - A
+ * at the end of the path. */
+static smartlist_t *
+build_vanguard_middle_exclude_list(uint8_t purpose,
+   cpath_build_state_t *state,
+   crypt_path_t *head,
+   int cur_len)
+{
+  smartlist_t *excluded;
+  const node_t *r;
+  crypt_path_t *cpath;
+  int i;
+
+  (void) purpose;
+
+  excluded = smartlist_new();
+
+  /* Add the exit to the exclude list (note that the exit/last hop is always
+   * chosen first in circuit_establish_circuit()). */
+  if ((r = build_state_get_exit_node(state))) {
+smartlist_add(excluded, (node_t*)r);
+  }
+
+  for (i = 0, cpath = head; cpath && i < cur_len; ++i, cpath=cpath->next) {
+if ((r = node_get_by_id(cpath->extend_info->identity_digest))) {
+  smartlist_add(excluded, (node_t*)r);
+}
+  }
+
+  return excluded;
+}
+
+/**
  * Build a list of nodes to exclude from the choice of this middle
  * hop, based on already chosen nodes.
- *
- * XXX: At present, this function does not exclude any nodes from
- * the vanguard circuits. See
- * https://trac.torproject.org/projects/tor/ticket/24487
  */
 static smartlist_t *
 build_middle_exclude_list(uint8_t purpose,
@@ -2463,32 +2507,21 @@ build_middle_exclude_list(uint8_t purpose,
   crypt_path_t *cpath;
   int i;
 
+  /** Vanguard circuits have their own path selection rules */
+  if (circuit_should_use_vanguards(purpose)) {
+return build_vanguard_middle_exclude_list(purpose, state, head, cur_len);
+  }
+
   excluded = smartlist_new();
 
-  /* Add the exit to the exclude list (note that the exit/last hop is always
-   * chosen first in circuit_establish_circuit()). */
+  /* For non-vanguard circuits, add the exit and its family to the exclude list
+   * (note that the exit/last hop is always chosen first in
+   * circuit_establish_circuit()). */
   if ((r = build_state_get_exit_node(state))) {
 nodelist_add_node_and_family(excluded, r);
   }
 
-  /* XXX: We don't apply any other previously selected node restrictions for
-   * vanguards, and allow nodes to be reused for those hop positions in the
-   * same circuit. This is because after many rotations, you get to learn
-   * inner guard nodes through the nodes that are not selected for outer
-   * hops.
-   *
-   * The alternative is building the circuit in reverse. Reverse calls to
-   * onion_extend_cpath() (ie: select outer hops first) would then have the
-   * property that you don't gain information about inner hops by observing
-   * outer ones. See https://trac.torproject.org/projects/tor/ticket/24487
-   * for this.
-   *
-   * (Note further that we can and do still exclude the exit in the block
-   * above, because it is chosen first in circuit_establish_circuit()..) */
-  if (circuit_should_use_vanguards(purpose)) {
-return excluded;
-  }
-
+  /* also exclude all other already chosen nodes and their family */
   for (i = 0, cpath = head; cpath && i < cur_len; ++i, cpath=cpath->next) {
 if ((r = node_get_by_id(cpath->extend_info->identity_digest))) {
   nodelist_add_node_and_family(excluded, r);



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Merge remote-tracking branch 'mikeperry/bug25870_rebase'

2018-05-08 Thread nickm
commit 5edc72a45b7479f5fe791054aa19f6b3b478c725
Merge: 2a4439adf e716c9212
Author: Nick Mathewson 
Date:   Tue May 8 14:12:29 2018 -0400

Merge remote-tracking branch 'mikeperry/bug25870_rebase'

 changes/bug25870   |   6 ++
 doc/tor.1.txt  |  16 
 src/or/circuitbuild.c  | 109 +---
 src/or/circuitbuild.h  |   7 ++
 src/or/entrynodes.c|  11 ++-
 src/or/entrynodes.h|   1 +
 src/test/test_entrynodes.c | 201 ++---
 7 files changed, 307 insertions(+), 44 deletions(-)

diff --cc src/test/test_entrynodes.c
index 6af18f8f4,c97aced04..cfcb88a66
--- a/src/test/test_entrynodes.c
+++ b/src/test/test_entrynodes.c
@@@ -14,9 -15,9 +15,10 @@@
  
  #include "bridges.h"
  #include "circuitlist.h"
+ #include "circuitbuild.h"
  #include "config.h"
  #include "confparse.h"
 +#include "crypto_rand.h"
  #include "directory.h"
  #include "entrynodes.h"
  #include "nodelist.h"

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Bug 25870: Allow 4th hop of vanguard circuits to be the guard.

2018-05-08 Thread nickm
commit 289c04b065b7b36734d73fc11a516b3cdc9dd702
Author: Mike Perry 
Date:   Tue May 1 00:59:21 2018 +

Bug 25870: Allow 4th hop of vanguard circuits to be the guard.

This prevents a malicious RP/IP from learning the guard node in the case 
that
we are using only one (because we aren't using two guards, or because one of
those two guards is temporarily down).

This ensures the "strong" version of Property #6 from
https://lists.torproject.org/pipermail/tor-dev/2018-April/013098.html
(Information about the guard(s) does not leak to the website/RP at all).
---
 src/or/circuitbuild.c | 19 +--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 4bdc8a3ee..68ff964f6 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -2447,8 +2447,10 @@ cpath_get_n_hops(crypt_path_t **head_ptr)
 /**
  * Build the exclude list for vanguard circuits.
  *
- * For vanguard circuits we exclude all the already chosen nodes (including
- * the exit) from being middle hops.
+ * For vanguard circuits we exclude all the already chosen nodes (including the
+ * exit) from being middle hops to prevent the creation of A - B - A subpaths.
+ * We also allow the 4th hop to be the same as the guard node so as to not leak
+ * guard information to RP/IP/HSDirs.
  *
  * For vanguard circuits, we don't apply any subnet or family restrictions.
  * This is to avoid impossible-to-build circuit paths, or just situations where
@@ -2483,6 +2485,19 @@ build_vanguard_middle_exclude_list(uint8_t purpose,
 smartlist_add(excluded, (node_t*)r);
   }
 
+  /* If we are picking the 4th hop, allow that node to be the guard too.
+   * This prevents us from avoiding the Guard for those hops, which
+   * gives the adversary information about our guard if they control
+   * the RP, IP, or HSDIR. We don't do this check based on purpose
+   * because we also want to allow HS_VANGUARDS pre-build circuits
+   * to use the guard for that last hop.
+   */
+  if (cur_len == DEFAULT_ROUTE_LEN+1) {
+/* Skip the first hop for the exclude list below */
+head = head->next;
+cur_len--;
+  }
+
   for (i = 0, cpath = head; cpath && i < cur_len; ++i, cpath=cpath->next) {
 if ((r = node_get_by_id(cpath->extend_info->identity_digest))) {
   smartlist_add(excluded, (node_t*)r);



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Changes file for bug25870.

2018-05-08 Thread nickm
commit 98dea0bc638e6338b7a1c5d84fcc4b4e7455ded2
Author: Mike Perry 
Date:   Fri Apr 20 19:38:48 2018 +

Changes file for bug25870.
---
 changes/bug25870 | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/changes/bug25870 b/changes/bug25870
new file mode 100644
index 0..aea5a1e30
--- /dev/null
+++ b/changes/bug25870
@@ -0,0 +1,6 @@
+  o Minor bugfixes (vanguards):
+- Allow the last hop in a vanguard circuit to be the same as our first,
+  to prevent the adversary from influencing guard node choice by choice
+  of last hop. Also prevent the creation of A - B - A paths, or A - A
+  paths, which are forbidden by relays. Fixes bug 25870; bugfix on
+  0.3.3.1-alpha.



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [torspec/master] Mention how HSLayer2Nodes and HSLayer3Nodes alter path restrictions.

2018-05-08 Thread nickm
commit 2058ddded039f532c61a94cdfcb190f2e8f74b1d
Author: Mike Perry 
Date:   Tue May 8 16:39:10 2018 +

Mention how HSLayer2Nodes and HSLayer3Nodes alter path restrictions.
---
 path-spec.txt | 5 +
 1 file changed, 5 insertions(+)

diff --git a/path-spec.txt b/path-spec.txt
index 0122dc5..15d9a3b 100644
--- a/path-spec.txt
+++ b/path-spec.txt
@@ -339,6 +339,11 @@ of their choices.
  , and the request is only supported by the exit whose nickname
  or fingerprint is .
 
+   - When set, "HSLayer2Nodes" and "HSLayer3Nodes" relax Tor's path
+ restrictions to allow nodes in the same /16 and node family to reappear
+ in the path. They also allow the guard node to be chosen as the RP, IP,
+ and HSDIR, and as the hop before those positions.
+
 2.3. Cannibalizing circuits
 
If we need a circuit and have a clean one already established, in

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Write unittests to check basic vanguard path selection.

2018-05-08 Thread nickm
commit 627d2fdbf0903498807fdd21c59a91502d731f7d
Author: George Kadianakis 
Date:   Fri Apr 27 15:27:17 2018 +0300

Write unittests to check basic vanguard path selection.

Adds two unittests:
- First checks the path selection of basic Tor circs.
- Second checks the path selection of vanguard circs.

There is a TODO on the second unittest that we might want to test sooner 
than
later, but it's not trivial to do it right now.

To do these unittests we needed the following mods:
- Make some functions STATIC.
- Add some more fields to the big fake network nodes of test_entrynodes.c
- Switch fake node nicknames to base32 (because base64 does not produce 
valid nicknames).
---
 src/or/circuitbuild.c  |   7 +-
 src/or/circuitbuild.h  |   7 ++
 src/test/test_entrynodes.c | 201 ++---
 3 files changed, 199 insertions(+), 16 deletions(-)

diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 68ff964f6..74e607d18 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -72,10 +72,7 @@ static channel_t * channel_connect_for_circuit(const 
tor_addr_t *addr,
 static int circuit_deliver_create_cell(circuit_t *circ,
const create_cell_t *create_cell,
int relayed);
-static int onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit,
- int is_hs_v3_rp_circuit);
 static crypt_path_t *onion_next_hop_in_cpath(crypt_path_t *cpath);
-static int onion_extend_cpath(origin_circuit_t *circ);
 STATIC int onion_append_hop(crypt_path_t **head_ptr, extend_info_t *choice);
 static int circuit_send_first_onion_skin(origin_circuit_t *circ);
 static int circuit_build_no_more_hops(origin_circuit_t *circ);
@@ -2285,7 +2282,7 @@ warn_if_last_router_excluded(origin_circuit_t *circ,
  * be used as an HS v3 rendezvous point.
  *
  * Return 0 if ok, -1 if circuit should be closed. */
-static int
+STATIC int
 onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit_ei,
   int is_hs_v3_rp_circuit)
 {
@@ -2719,7 +2716,7 @@ onion_next_hop_in_cpath(crypt_path_t *cpath)
  * Return 1 if the path is complete, 0 if we successfully added a hop,
  * and -1 on error.
  */
-static int
+STATIC int
 onion_extend_cpath(origin_circuit_t *circ)
 {
   uint8_t purpose = circ->base_.purpose;
diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h
index bea31ad0d..ae4aef768 100644
--- a/src/or/circuitbuild.h
+++ b/src/or/circuitbuild.h
@@ -83,6 +83,13 @@ STATIC circid_t get_unique_circ_id_by_chan(channel_t *chan);
 STATIC int new_route_len(uint8_t purpose, extend_info_t *exit_ei,
  smartlist_t *nodes);
 MOCK_DECL(STATIC int, count_acceptable_nodes, (smartlist_t *nodes));
+
+STATIC int onion_extend_cpath(origin_circuit_t *circ);
+
+STATIC int
+onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit_ei,
+  int is_hs_v3_rp_circuit);
+
 #if defined(ENABLE_TOR2WEB_MODE) || defined(TOR_UNIT_TESTS)
 STATIC const node_t *pick_tor2web_rendezvous_node(router_crn_flags_t flags,
   const or_options_t *options);
diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c
index 92a860360..c97aced04 100644
--- a/src/test/test_entrynodes.c
+++ b/src/test/test_entrynodes.c
@@ -4,6 +4,7 @@
 #include "orconfig.h"
 
 #define CIRCUITLIST_PRIVATE
+#define CIRCUITBUILD_PRIVATE
 #define STATEFILE_PRIVATE
 #define ENTRYNODES_PRIVATE
 #define ROUTERLIST_PRIVATE
@@ -14,6 +15,7 @@
 
 #include "bridges.h"
 #include "circuitlist.h"
+#include "circuitbuild.h"
 #include "config.h"
 #include "confparse.h"
 #include "directory.h"
@@ -74,6 +76,17 @@ bfn_mock_node_get_by_id(const char *id)
   return NULL;
 }
 
+/* Helper function to free a test node. */
+static void
+test_node_free(node_t *n)
+{
+  tor_free(n->rs);
+  tor_free(n->md->onion_curve25519_pkey);
+  short_policy_free(n->md->exit_policy);
+  tor_free(n->md);
+  tor_free(n);
+}
+
 /* Unittest cleanup function: Cleanup the fake network. */
 static int
 big_fake_network_cleanup(const struct testcase_t *testcase, void *ptr)
@@ -83,9 +96,7 @@ big_fake_network_cleanup(const struct testcase_t *testcase, 
void *ptr)
 
   if (big_fake_net_nodes) {
 SMARTLIST_FOREACH(big_fake_net_nodes, node_t *, n, {
-  tor_free(n->rs);
-  tor_free(n->md);
-  tor_free(n);
+  test_node_free(n);
 });
 smartlist_free(big_fake_net_nodes);
   }
@@ -113,9 +124,18 @@ big_fake_network_setup(const struct testcase_t *testcase)
 
   big_fake_net_nodes = smartlist_new();
   for (i = 0; i < N_NODES; ++i) {
+curve25519_secret_key_t curve25519_secret_key;
+
 node_t *n = tor_malloc_zero(sizeof(node_t));
 n->md = tor_malloc_zero(sizeof(microdesc_t));
 
+/* Generate curve25519 key for this node */
+n->md->onion_curve25519_pkey =
+  

[tor-commits] [tor/master] Bug 25870: Allow the last hop in a vanguard circuit to be our guard.

2018-05-08 Thread nickm
commit d634c1ba6b3b5b4773ee2bc7095a004818431541
Author: Mike Perry 
Date:   Fri Apr 20 18:58:15 2018 +

Bug 25870: Allow the last hop in a vanguard circuit to be our guard.

The last hop in vanguard circuits can be an RP/IP/HSDir.

Since vanguard circuits are at least 3 hops (sometimes 4) before this node,
this change will not cause A - B - A paths.
---
 src/or/circuitbuild.c |  2 +-
 src/or/entrynodes.c   | 11 +--
 src/or/entrynodes.h   |  1 +
 3 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 54446bb01..75540e5d3 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -2628,7 +2628,7 @@ choose_good_entry_server(uint8_t purpose, 
cpath_build_state_t *state,
 /* This request is for an entry server to use for a regular circuit,
  * and we use entry guard nodes.  Just return one of the guard nodes.  */
 tor_assert(guard_state_out);
-return guards_choose_guard(state, guard_state_out);
+return guards_choose_guard(state, purpose, guard_state_out);
   }
 
   excluded = smartlist_new();
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 88d1b94de..34868846f 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -118,6 +118,7 @@
 #include "circpathbias.h"
 #include "circuitbuild.h"
 #include "circuitlist.h"
+#include "circuituse.h"
 #include "circuitstats.h"
 #include "config.h"
 #include "confparse.h"
@@ -3473,12 +3474,18 @@ guards_update_all(void)
 used. */
 const node_t *
 guards_choose_guard(cpath_build_state_t *state,
-   circuit_guard_state_t **guard_state_out)
+uint8_t purpose,
+circuit_guard_state_t **guard_state_out)
 {
   const node_t *r = NULL;
   const uint8_t *exit_id = NULL;
   entry_guard_restriction_t *rst = NULL;
-  if (state && (exit_id = build_state_get_exit_rsa_id(state))) {
+
+  /* Only apply restrictions if we have a specific exit node in mind, and only
+   * if we are not doing vanguard circuits: we don't want to apply guard
+   * restrictions to vanguard circuits. */
+  if (state && !circuit_should_use_vanguards(purpose) &&
+  (exit_id = build_state_get_exit_rsa_id(state))) {
 /* We're building to a targeted exit node, so that node can't be
  * chosen as our guard for this circuit.  Remember that fact in a
  * restriction. */
diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
index d56249831..e8c91da41 100644
--- a/src/or/entrynodes.h
+++ b/src/or/entrynodes.h
@@ -322,6 +322,7 @@ struct circuit_guard_state_t {
 /* Common entry points for old and new guard code */
 int guards_update_all(void);
 const node_t *guards_choose_guard(cpath_build_state_t *state,
+  uint8_t purpose,
   circuit_guard_state_t **guard_state_out);
 const node_t *guards_choose_dirguard(uint8_t dir_purpose,
  circuit_guard_state_t **guard_state_out);



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Bug 25870: Mention path restriction differences in manpage.

2018-05-08 Thread nickm
commit e716c92127f0da2fc5758c091a9e33857cd5e5d5
Author: Mike Perry 
Date:   Tue May 8 16:35:20 2018 +

Bug 25870: Mention path restriction differences in manpage.
---
 doc/tor.1.txt | 16 
 1 file changed, 16 insertions(+)

diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index 05a612d6a..2f74d567e 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -1574,6 +1574,14 @@ The following options are useful only for clients (that 
is, if
 which means that nodes specified in ExcludeNodes will not be
 picked.
  +
+When either this option or HSLayer3Nodes are set, the /16 subnet
+and node family restrictions are removed for hidden service
+circuits. Additionally, we allow the guard node to be present
+as the Rend, HSDir, and IP node, and as the hop before it. This
+is done to prevent the adversary from inferring information
+about our guard, layer2, and layer3 node choices at later points
+in the path.
+ +
 This option is meant to be managed by a Tor controller such as
 https://github.com/mikeperry-tor/vanguards that selects and
 updates this set of nodes for you. Hence it does not do load
@@ -1619,6 +1627,14 @@ The following options are useful only for clients (that 
is, if
 ExcludeNodes have higher priority than HSLayer3Nodes,
 which means that nodes specified in ExcludeNodes will not be
 picked.
+ +
+When either this option or HSLayer2Nodes are set, the /16 subnet
+and node family restrictions are removed for hidden service
+circuits. Additionally, we allow the guard node to be present
+as the Rend, HSDir, and IP node, and as the hop before it. This
+is done to prevent the adversary from inferring information
+about our guard, layer2, and layer3 node choices at later points
+in the path.
   +
 This option is meant to be managed by a Tor controller such as
 https://github.com/mikeperry-tor/vanguards that selects and



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Fix memleak found by unittests.

2018-05-08 Thread nickm
commit e17f436fff541e0c31827f0e99bd345096d276e0
Author: George Kadianakis 
Date:   Fri Apr 27 15:27:44 2018 +0300

Fix memleak found by unittests.
---
 src/or/circuitbuild.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 74e607d18..1eb3947ae 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -2633,7 +2633,9 @@ choose_good_middle_server(uint8_t purpose,
   /** If a hidden service circuit wants a specific middle node, pin it. */
   if (middle_node_must_be_vanguard(options, purpose, cur_len)) {
 log_debug(LD_GENERAL, "Picking a sticky node (cur_len = %d)", cur_len);
-return pick_vanguard_middle_node(options, flags, cur_len, excluded);
+choice = pick_vanguard_middle_node(options, flags, cur_len, excluded);
+smartlist_free(excluded);
+return choice;
   }
 
   choice = router_choose_random_node(excluded, options->ExcludeNodes, flags);



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Merge branch 'ticket26008'

2018-05-08 Thread nickm
commit 2a4439adf37ed75c8f7d2db3134d0263f70de796
Merge: bf5eaa82d 6e3e96d2f
Author: Nick Mathewson 
Date:   Tue May 8 14:09:38 2018 -0400

Merge branch 'ticket26008'

 changes/ticket26008   |  7 +++
 src/test/test_workqueue.c | 12 +---
 2 files changed, 16 insertions(+), 3 deletions(-)

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Fix the selection of events to cancel in test_workqueue.c

2018-05-08 Thread nickm
commit 6e3e96d2ff0c1b83bdd3f2059d1b4a2b96a53341
Author: Nick Mathewson 
Date:   Sun May 6 21:03:26 2018 -0400

Fix the selection of events to cancel in test_workqueue.c

Our previous algorithm had a nonzero probability of picking no
events to cancel, which is of course incorrect.  The new code uses
Vitter's good old reservoir sampling "algorithm R" from 1985.

Fixes bug 26008; bugfix on 0.2.6.3-alpha.
---
 changes/ticket26008   |  7 +++
 src/test/test_workqueue.c | 12 +---
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/changes/ticket26008 b/changes/ticket26008
new file mode 100644
index 0..7550c959e
--- /dev/null
+++ b/changes/ticket26008
@@ -0,0 +1,7 @@
+  o Minor bugfixes (test):
+- When testing workqueue event-cancellation, make sure that we actually
+  cancel an event, and that cancel each event with equal probability.
+  (It was previously possible, though extremely unlikely, for our
+  event-canceling test not to cancel any events.) Fixes bug 26008;
+  bugfix on 0.2.6.3-alpha.  
+
diff --git a/src/test/test_workqueue.c b/src/test/test_workqueue.c
index 8d29d2062..cc7073850 100644
--- a/src/test/test_workqueue.c
+++ b/src/test/test_workqueue.c
@@ -224,7 +224,8 @@ add_n_work_items(threadpool_t *tp, int n)
   workqueue_entry_t **to_cancel;
   workqueue_entry_t *ent;
 
-  to_cancel = tor_malloc(sizeof(workqueue_entry_t*) * opt_n_cancel);
+  // We'll choose randomly which entries to cancel.
+  to_cancel = tor_calloc(opt_n_cancel, sizeof(workqueue_entry_t*));
 
   while (n_queued++ < n) {
 ent = add_work(tp);
@@ -233,9 +234,14 @@ add_n_work_items(threadpool_t *tp, int n)
   tor_libevent_exit_loop_after_delay(tor_libevent_get_base(), NULL);
   return -1;
 }
-if (n_try_cancel < opt_n_cancel &&
-tor_weak_random_range(_rng, n) < opt_n_cancel) {
+
+if (n_try_cancel < opt_n_cancel) {
   to_cancel[n_try_cancel++] = ent;
+} else {
+  int p = tor_weak_random_range(_rng, n_queued);
+  if (p < n_try_cancel) {
+to_cancel[p] = ent;
+  }
 }
   }
 



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] Merge branch 'maint-0.3.3'

2018-05-08 Thread arma
commit bf5eaa82da4214be681cf0674f24376b7c4c0e34
Merge: c3ae14549 b979415e8
Author: Roger Dingledine 
Date:   Tue May 8 13:49:56 2018 -0400

Merge branch 'maint-0.3.3'

 changes/bug26052 | 6 ++
 doc/tor.1.txt| 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] manpage fix to stop saying CacheIPv4DNS is on by default

2018-05-08 Thread arma
commit b979415e8bf4c33e6d540c780edeeb40bce5e512
Author: Roger Dingledine 
Date:   Tue May 8 13:13:45 2018 -0400

manpage fix to stop saying CacheIPv4DNS is on by default

Stop saying in the manual that clients cache ipv4 dns answers from exit
relays. We haven't used them since 0.2.6.3-alpha, and in ticket 24050
we stopped even caching them as of 0.3.2.6-alpha, but we forgot to say
so in the man page.

Fixes bug 26052; bugfix on 0.3.2.6-alpha.
---
 changes/bug26052 | 6 ++
 doc/tor.1.txt| 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/changes/bug26052 b/changes/bug26052
new file mode 100644
index 0..4721933fa
--- /dev/null
+++ b/changes/bug26052
@@ -0,0 +1,6 @@
+  o Minor bugfixes (documentation):
+- Stop saying in the manual that clients cache ipv4 dns answers
+  from exit relays. We haven't used them since 0.2.6.3-alpha, and
+  in ticket 24050 we stopped even caching them as of 0.3.2.6-alpha,
+  but we forgot to say so in the man page. Fixes bug 26052; bugfix
+  on 0.3.2.6-alpha.
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index 53a8c8fe5..f89406180 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -1237,7 +1237,7 @@ The following options are useful only for clients (that 
is, if
 flag is not supported.
 **CacheIPv4DNS**;;
 Tells the client to remember IPv4 DNS answers we receive from exit
-nodes via this connection. (On by default.)
+nodes via this connection.
 **CacheIPv6DNS**;;
 Tells the client to remember IPv6 DNS answers we receive from exit
 nodes via this connection.



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/release-0.3.3] Merge branch 'maint-0.3.3' into release-0.3.3

2018-05-08 Thread arma
commit 6db0c006b2d4d1244f9e4fa486ff7ad66a7ccb47
Merge: 0e4f7b56a b979415e8
Author: Roger Dingledine 
Date:   Tue May 8 13:49:34 2018 -0400

Merge branch 'maint-0.3.3' into release-0.3.3

 changes/bug26052 | 6 ++
 doc/tor.1.txt| 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/release-0.3.3] manpage fix to stop saying CacheIPv4DNS is on by default

2018-05-08 Thread arma
commit b979415e8bf4c33e6d540c780edeeb40bce5e512
Author: Roger Dingledine 
Date:   Tue May 8 13:13:45 2018 -0400

manpage fix to stop saying CacheIPv4DNS is on by default

Stop saying in the manual that clients cache ipv4 dns answers from exit
relays. We haven't used them since 0.2.6.3-alpha, and in ticket 24050
we stopped even caching them as of 0.3.2.6-alpha, but we forgot to say
so in the man page.

Fixes bug 26052; bugfix on 0.3.2.6-alpha.
---
 changes/bug26052 | 6 ++
 doc/tor.1.txt| 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/changes/bug26052 b/changes/bug26052
new file mode 100644
index 0..4721933fa
--- /dev/null
+++ b/changes/bug26052
@@ -0,0 +1,6 @@
+  o Minor bugfixes (documentation):
+- Stop saying in the manual that clients cache ipv4 dns answers
+  from exit relays. We haven't used them since 0.2.6.3-alpha, and
+  in ticket 24050 we stopped even caching them as of 0.3.2.6-alpha,
+  but we forgot to say so in the man page. Fixes bug 26052; bugfix
+  on 0.3.2.6-alpha.
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index 53a8c8fe5..f89406180 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -1237,7 +1237,7 @@ The following options are useful only for clients (that 
is, if
 flag is not supported.
 **CacheIPv4DNS**;;
 Tells the client to remember IPv4 DNS answers we receive from exit
-nodes via this connection. (On by default.)
+nodes via this connection.
 **CacheIPv6DNS**;;
 Tells the client to remember IPv6 DNS answers we receive from exit
 nodes via this connection.



___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/maint-0.3.3] manpage fix to stop saying CacheIPv4DNS is on by default

2018-05-08 Thread arma
commit b979415e8bf4c33e6d540c780edeeb40bce5e512
Author: Roger Dingledine 
Date:   Tue May 8 13:13:45 2018 -0400

manpage fix to stop saying CacheIPv4DNS is on by default

Stop saying in the manual that clients cache ipv4 dns answers from exit
relays. We haven't used them since 0.2.6.3-alpha, and in ticket 24050
we stopped even caching them as of 0.3.2.6-alpha, but we forgot to say
so in the man page.

Fixes bug 26052; bugfix on 0.3.2.6-alpha.
---
 changes/bug26052 | 6 ++
 doc/tor.1.txt| 2 +-
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/changes/bug26052 b/changes/bug26052
new file mode 100644
index 0..4721933fa
--- /dev/null
+++ b/changes/bug26052
@@ -0,0 +1,6 @@
+  o Minor bugfixes (documentation):
+- Stop saying in the manual that clients cache ipv4 dns answers
+  from exit relays. We haven't used them since 0.2.6.3-alpha, and
+  in ticket 24050 we stopped even caching them as of 0.3.2.6-alpha,
+  but we forgot to say so in the man page. Fixes bug 26052; bugfix
+  on 0.3.2.6-alpha.
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index 53a8c8fe5..f89406180 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -1237,7 +1237,7 @@ The following options are useful only for clients (that 
is, if
 flag is not supported.
 **CacheIPv4DNS**;;
 Tells the client to remember IPv4 DNS answers we receive from exit
-nodes via this connection. (On by default.)
+nodes via this connection.
 **CacheIPv6DNS**;;
 Tells the client to remember IPv6 DNS answers we receive from exit
 nodes via this connection.

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor/master] minor cleanups on commit 17daab76

2018-05-08 Thread arma
commit c3ae14549d48cf9266b6442cce3bb15df613a7a8
Author: Roger Dingledine 
Date:   Tue May 8 12:21:24 2018 -0400

minor cleanups on commit 17daab76

better punctuation and clearer wording
---
 src/or/hs_stats.c | 6 +++---
 src/or/status.c   | 6 +++---
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/or/hs_stats.c b/src/or/hs_stats.c
index 3e183a5bf..1e2a96945 100644
--- a/src/or/hs_stats.c
+++ b/src/or/hs_stats.c
@@ -3,7 +3,7 @@
 
 /**
  * \file hs_stats.c
- * \brief Keeps stats about the activity of our hidden service.
+ * \brief Keeps stats about the activity of our onion service(s).
  **/
 
 #include "or.h"
@@ -42,14 +42,14 @@ hs_stats_get_n_introduce2_v2_cells(void)
   return n_introduce2_v2;
 }
 
-/** Note that we attempted to launch another circuit to a rendezvous point */
+/** Note that we attempted to launch another circuit to a rendezvous point. */
 void
 hs_stats_note_service_rendezvous_launch(void)
 {
   n_rendezvous_launches++;
 }
 
-/** Return the number of rendezvous circuits we have attempted to launch */
+/** Return the number of rendezvous circuits we have attempted to launch. */
 uint32_t
 hs_stats_get_n_rendezvous_launches(void)
 {
diff --git a/src/or/status.c b/src/or/status.c
index 4c497739e..4b8033d11 100644
--- a/src/or/status.c
+++ b/src/or/status.c
@@ -87,19 +87,19 @@ bytes_to_usage(uint64_t bytes)
   return bw_string;
 }
 
-/** Log some usage info about our hidden service */
+/** Log some usage info about our onion service(s). */
 static void
 log_onion_service_stats(void)
 {
   unsigned int num_services = hs_service_get_num_services();
 
-  /* If there are no active hidden services, no need to print logs */
+  /* If there are no active onion services, no need to print logs */
   if (num_services == 0) {
 return;
   }
 
   log_notice(LD_HEARTBEAT,
- "Our hidden service%s received %u v2 and %u v3 INTRODUCE2 cells "
+ "Our onion service%s received %u v2 and %u v3 INTRODUCE2 cells "
  "and attempted to launch %d rendezvous circuits.",
  num_services == 1 ? "" : "s",
  hs_stats_get_n_introduce2_v2_cells(),

___
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

2018-05-08 Thread translation
commit 69d4373182dcbdd56e35e35e8763f9e0436bb652
Author: Translation commit bot 
Date:   Tue May 8 11:45:49 2018 +

Update translations for liveusb-creator_completed
---
 ru/ru.po | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/ru/ru.po b/ru/ru.po
index 9ab550183..258c6893b 100644
--- a/ru/ru.po
+++ b/ru/ru.po
@@ -18,6 +18,7 @@
 # Oul Gocke , 2013-2014
 # Roberto Brigante, 2017
 # Sergey Briskin, 2014
+# sgtStrom, 2018
 # tavarysh , 2013
 # Vladimir.Serykh , 2015
 # vlasok , 2012
@@ -30,8 +31,8 @@ msgstr ""
 "Project-Id-Version: The Tor Project\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2017-11-10 15:57+0100\n"
-"PO-Revision-Date: 2018-04-12 18:59+\n"
-"Last-Translator: IDRASSI Mounir \n"
+"PO-Revision-Date: 2018-05-08 11:20+\n"
+"Last-Translator: sgtStrom\n"
 "Language-Team: Russian 
(http://www.transifex.com/otf/torproject/language/ru/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -45,7 +46,7 @@ msgstr "Вы должны запустить 
приложение с root пра
 
 #: ../tails_installer/creator.py:147
 msgid "Extracting live image to the target device..."
-msgstr "Извлеките образ на необходимом 
устройстве..."
+msgstr "Извлечение образа на целевое 
устройство..."
 
 #: ../tails_installer/creator.py:154
 #, python-format

___
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

2018-05-08 Thread translation
commit 9da93d8055227e14fdb744518f15065c77a83065
Author: Translation commit bot 
Date:   Tue May 8 11:45:42 2018 +

Update translations for liveusb-creator
---
 ru/ru.po | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/ru/ru.po b/ru/ru.po
index 9ab550183..258c6893b 100644
--- a/ru/ru.po
+++ b/ru/ru.po
@@ -18,6 +18,7 @@
 # Oul Gocke , 2013-2014
 # Roberto Brigante, 2017
 # Sergey Briskin, 2014
+# sgtStrom, 2018
 # tavarysh , 2013
 # Vladimir.Serykh , 2015
 # vlasok , 2012
@@ -30,8 +31,8 @@ msgstr ""
 "Project-Id-Version: The Tor Project\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2017-11-10 15:57+0100\n"
-"PO-Revision-Date: 2018-04-12 18:59+\n"
-"Last-Translator: IDRASSI Mounir \n"
+"PO-Revision-Date: 2018-05-08 11:20+\n"
+"Last-Translator: sgtStrom\n"
 "Language-Team: Russian 
(http://www.transifex.com/otf/torproject/language/ru/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -45,7 +46,7 @@ msgstr "Вы должны запустить 
приложение с root пра
 
 #: ../tails_installer/creator.py:147
 msgid "Extracting live image to the target device..."
-msgstr "Извлеките образ на необходимом 
устройстве..."
+msgstr "Извлечение образа на целевое 
устройство..."
 
 #: ../tails_installer/creator.py:154
 #, python-format

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor-and-https_completed] Update translations for tor-and-https_completed

2018-05-08 Thread translation
commit b60d5b92c435978909c73c119c9df6a785f38c7d
Author: Translation commit bot 
Date:   Tue May 8 11:17:40 2018 +

Update translations for tor-and-https_completed
---
 fr.po | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fr.po b/fr.po
index 198029d0c..57815b6d2 100644
--- a/fr.po
+++ b/fr.po
@@ -9,8 +9,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: The Tor Project\n"
 "POT-Creation-Date: 2014-07-17 14:23+\n"
-"PO-Revision-Date: 2018-04-12 19:08+\n"
-"Last-Translator: French language coordinator \n"
+"PO-Revision-Date: 2018-05-08 11:15+\n"
+"Last-Translator: Madeline Earp \n"
 "Language-Team: French 
(http://www.transifex.com/otf/torproject/language/fr/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [translation/tor-and-https] Update translations for tor-and-https

2018-05-08 Thread translation
commit fe8329719fadc950d69bfddbaa8d1d82a14aa8c1
Author: Translation commit bot 
Date:   Tue May 8 11:17:36 2018 +

Update translations for tor-and-https
---
 fr.po | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/fr.po b/fr.po
index 198029d0c..57815b6d2 100644
--- a/fr.po
+++ b/fr.po
@@ -9,8 +9,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: The Tor Project\n"
 "POT-Creation-Date: 2014-07-17 14:23+\n"
-"PO-Revision-Date: 2018-04-12 19:08+\n"
-"Last-Translator: French language coordinator \n"
+"PO-Revision-Date: 2018-05-08 11:15+\n"
+"Last-Translator: Madeline Earp \n"
 "Language-Team: French 
(http://www.transifex.com/otf/torproject/language/fr/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits


[tor-commits] [tor-browser-build/master] Bug 25318: Add Tor Browser nightly builds email notification

2018-05-08 Thread gk
commit 4580c03c937e8ccab86446d60a0d4ee29b7c07c8
Author: Nicolas Vigier 
Date:   Mon Apr 23 13:35:39 2018 +0200

Bug 25318: Add Tor Browser nightly builds email notification

Authentication configuration for the email setup is stored in
group_vars/boklm-tbb-nightly/dma-auth.yml, encrypted using
ansible-vault. The file contains the dma_auth_conf variable, which is
the content of the /etc/dma/auth.conf file.
---
 tools/ansible/Makefile |  2 +-
 tools/ansible/boklm-tbb-nightly-build.yml  |  1 +
 .../ansible/group_vars/boklm-tbb-nightly/dma-auth.yml  | 10 ++
 tools/ansible/group_vars/boklm-tbb-nightly/dma.yml |  8 
 .../group_vars/boklm-tbb-nightly/tbb-nightly-build.yml |  2 ++
 tools/ansible/roles/mta/tasks/main.yml | 18 ++
 .../roles/tbb-nightly-build/templates/testsuite-config |  5 +
 7 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/tools/ansible/Makefile b/tools/ansible/Makefile
index 72deb5b..ea63a44 100644
--- a/tools/ansible/Makefile
+++ b/tools/ansible/Makefile
@@ -5,4 +5,4 @@ fpcentral:
ANSIBLE_CONFIG='$(@D)/ansible-fpcentral.cfg' ansible-playbook -i 
inventory --ask-become-pass fpcentral.yml
 
 boklm-tbb-nightly-build:
-   ansible-playbook -i inventory boklm-tbb-nightly-build.yml
+   ansible-playbook 
--vault-password-file=~/ansible-vault/boklm-tbb-nightly -i inventory 
boklm-tbb-nightly-build.yml
diff --git a/tools/ansible/boklm-tbb-nightly-build.yml 
b/tools/ansible/boklm-tbb-nightly-build.yml
index cc37e23..2fe48cd 100644
--- a/tools/ansible/boklm-tbb-nightly-build.yml
+++ b/tools/ansible/boklm-tbb-nightly-build.yml
@@ -5,3 +5,4 @@
   - role: tbb-builder
   - role: tbb-nightly-build
   - role: unattended-upgrades
+  - role: mta
diff --git a/tools/ansible/group_vars/boklm-tbb-nightly/dma-auth.yml 
b/tools/ansible/group_vars/boklm-tbb-nightly/dma-auth.yml
new file mode 100644
index 000..254291c
--- /dev/null
+++ b/tools/ansible/group_vars/boklm-tbb-nightly/dma-auth.yml
@@ -0,0 +1,10 @@
+$ANSIBLE_VAULT;1.1;AES256
+64353537366566623534653938363036396164303631616138313130663766626463303034336564
+633934663963376538353465356164636662666539340a343533636436333838633039363265
+33393762363563323338356634396137393466616336326337323761643332363438313735646135
+6633326462616261310a66373830646361323732616466353332623031666233393561636334
+6133643363396464363165323063386139313164653266653665373837626138653535663262
+30303761333230623662323037376130386134373939613861343233363038636464623132363135
+6638653234616530383934656338393463346238653438333063643235616238383332353930
+39316439653733376239343661373265303033323237366132366161316535636165336539333130
+3033
diff --git a/tools/ansible/group_vars/boklm-tbb-nightly/dma.yml 
b/tools/ansible/group_vars/boklm-tbb-nightly/dma.yml
new file mode 100644
index 000..b210a3a
--- /dev/null
+++ b/tools/ansible/group_vars/boklm-tbb-nightly/dma.yml
@@ -0,0 +1,8 @@
+---
+dma_conf: |
+SMARTHOST mail.riseup.net
+AUTHPATH /etc/dma/auth.conf
+SECURETRANSFER
+STARTTLS
+MAILNAME /etc/mailname
+MASQUERADE boklm-tbb-nigh...@riseup.net
diff --git a/tools/ansible/group_vars/boklm-tbb-nightly/tbb-nightly-build.yml 
b/tools/ansible/group_vars/boklm-tbb-nightly/tbb-nightly-build.yml
index ebaadfe..77c4ad6 100644
--- a/tools/ansible/group_vars/boklm-tbb-nightly/tbb-nightly-build.yml
+++ b/tools/ansible/group_vars/boklm-tbb-nightly/tbb-nightly-build.yml
@@ -1,3 +1,5 @@
 ---
 nightly_build_hostname: f4amtbsowhix7rrf.onion
 nightly_build_url: 'http://{{ nightly_build_hostname }}'
+nightly_build_email_from: "'Tor Browser Nightly Builds (boklm) 
',"
+nightly_build_email_to: "[ 'bo...@torproject.org', 'g...@torproject.org' ],"
diff --git a/tools/ansible/roles/mta/tasks/main.yml 
b/tools/ansible/roles/mta/tasks/main.yml
index de469d8..9c5ac49 100644
--- a/tools/ansible/roles/mta/tasks/main.yml
+++ b/tools/ansible/roles/mta/tasks/main.yml
@@ -4,3 +4,21 @@
   apt:
   name: dma
   state: present
+
+- name: create dma auth.conf
+  copy:
+  dest: /etc/dma/auth.conf
+  mode: 0640
+  owner: root
+  group: mail
+  content: "{{ dma_auth_conf }}"
+  when: dma_auth_conf is defined
+
+- name: create dma.conf
+  copy:
+  dest: /etc/dma/dma.conf
+  mode: 0640
+  owner: root
+  group: mail
+  content: "{{ dma_conf }}"
+  when: dma_conf is defined
diff --git a/tools/ansible/roles/tbb-nightly-build/templates/testsuite-config 
b/tools/ansible/roles/tbb-nightly-build/templates/testsuite-config
index b537f56..c07c52c 100644
--- a/tools/ansible/roles/tbb-nightly-build/templates/testsuite-config
+++ b/tools/ansible/roles/tbb-nightly-build/templates/testsuite-config
@@ -23,5 +23,10 @@ my %res = (
 name => $name,
 args => [ $testsuite ],
 tags => [ 'nightly' ],
+'reports-url' => '{{ 

[tor-commits] [tor-browser-build/master] Bug 25817: add ansible roles for tbb-nightly setup

2018-05-08 Thread gk
commit a2f565643d4c34a49712c37e3931dd6f80da7ba1
Author: Nicolas Vigier 
Date:   Mon Apr 16 19:30:02 2018 +0200

Bug 25817: add ansible roles for tbb-nightly setup
---
 README |  43 ++--
 tools/ansible/Makefile |   3 +
 tools/ansible/README   |   6 ++
 tools/ansible/boklm-tbb-nightly-build.yml  |   7 ++
 .../boklm-tbb-nightly/tbb-nightly-build.yml|   3 +
 tools/ansible/inventory|   4 +
 .../roles/tbb-nightly-build/defaults/main.yml  |  11 ++
 .../roles/tbb-nightly-build/handlers/main.yml  |   5 +
 .../ansible/roles/tbb-nightly-build/tasks/main.yml |  84 +++
 .../roles/tbb-nightly-build/templates/nginx.conf   |  16 +++
 .../tbb-nightly-build/templates/rbm.local.conf | 116 +
 .../tbb-nightly-build/templates/start-tbb-nightly  |   5 +
 .../tbb-nightly-build/templates/testsuite-config   |  27 +
 .../tbb-nightly-build/templates/www-index.html |  10 ++
 14 files changed, 306 insertions(+), 34 deletions(-)

diff --git a/README b/README
index d498c05..a20b659 100644
--- a/README
+++ b/README
@@ -138,43 +138,18 @@ Automated builds using tbb-testsuite
 
 
 The Tor Browser testsuite scripts can also be used to do nightly builds
-and publish the build logs.
+and publish the build logs. The recommended way to do that is to use
+the ansible roles from the tools/ansible directory. See next section
+for details.
 
-If you want to do that, start by cloning the git repository:
 
-   $ git clone 
https://git.torproject.org/boklm/tor-browser-bundle-testsuite.git
+Using ansible to set up a nightly build machine
+---
 
-Install some dependencies:
-
-   # apt-get install -y libdata-dump-perl libfile-slurp-perl \
-   libio-captureoutput-perl perlmagick libjson-perl \
-   libwww-perl liblwp-protocol-https-perl libtemplate-perl \
-   libyaml-syck-perl libdatetime-perl \
-   libemail-sender-perl libemail-simple-perl libfile-type-perl \
-   libipc-run-perl libxml-libxml-perl
-
-Copy the config/tor-browser_build-boklm file and edit it:
-
-   $ cd tor-browser-bundle-testsuite
-   $ cp config/tor-browser_build-boklm config/tor-browser_build-$user
-   $ vim config/tor-browser_build-$user
-
-Change the publish_dir and publish_url options. The publish_dir option is
-the local directory where the builds will be stored. The publish_url
-option is the public URL where the builds will be available.
-
-Copy the tools/tor-browser-builds-boklm file and edit it to change the
---config= option:
-
-   $ cp tools/tor-browser-builds-boklm tools/tor-browser-builds-$user
-   $ vim tools/tor-browser-builds-$user
-
-You can now run ./tools/tor-browser-builds-$user to start the build, and
-add it to your crontab.
-
-The html build reports will be available in the reports/ directory, and
-the build files in the tor-browser-builds/ directory (unless you changed
-the publish_dir option).
+The directory tools/ansible contains some ansible roles to set up a
+nightly build machine. You can look at the playbook defined in
+boklm-tbb-nightly-build.yml and variables in group_vars/boklm-tbb-nightly/
+for an example of how it can be used.
 
 
 Signing builds
diff --git a/tools/ansible/Makefile b/tools/ansible/Makefile
index 608f932..72deb5b 100644
--- a/tools/ansible/Makefile
+++ b/tools/ansible/Makefile
@@ -3,3 +3,6 @@ ansible-tbb-build:
 
 fpcentral:
ANSIBLE_CONFIG='$(@D)/ansible-fpcentral.cfg' ansible-playbook -i 
inventory --ask-become-pass fpcentral.yml
+
+boklm-tbb-nightly-build:
+   ansible-playbook -i inventory boklm-tbb-nightly-build.yml
diff --git a/tools/ansible/README b/tools/ansible/README
index 6b2e6a4..dc69ad7 100644
--- a/tools/ansible/README
+++ b/tools/ansible/README
@@ -16,3 +16,9 @@ fpcentral:
   you need to be in the fpcentral tpo ldap group. Your ldap password will
   be asked, to sudo to the fpcentral user.
 
+boklm-tbb-nightly-build:
+  This target is used by boklm to deploy a nightly build machine. If
+  anybody else wants to set up their own nightly builds, it is possible to
+  do it by adding a new host to the inventory file and making copies of
+  group_vars/boklm-tbb-nightly/ and boklm-tbb-nightly-build.yml.
+
diff --git a/tools/ansible/boklm-tbb-nightly-build.yml 
b/tools/ansible/boklm-tbb-nightly-build.yml
new file mode 100644
index 000..cc37e23
--- /dev/null
+++ b/tools/ansible/boklm-tbb-nightly-build.yml
@@ -0,0 +1,7 @@
+---
+
+- hosts: boklm-tbb-nightly-build
+  roles:
+  - role: tbb-builder
+  - role: tbb-nightly-build
+  - role: unattended-upgrades
diff --git a/tools/ansible/group_vars/boklm-tbb-nightly/tbb-nightly-build.yml 
b/tools/ansible/group_vars/boklm-tbb-nightly/tbb-nightly-build.yml
new file mode 100644
index 000..ebaadfe
--- 

[tor-commits] [translation/support-connecting] Update translations for support-connecting

2018-05-08 Thread translation
commit 3019288eb5dec7befeea1b05ec1d689afdd18043
Author: Translation commit bot 
Date:   Tue May 8 06:19:53 2018 +

Update translations for support-connecting
---
 bn_BD.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bn_BD.json b/bn_BD.json
index 9d86e19ce..217af122b 100644
--- a/bn_BD.json
+++ b/bn_BD.json
@@ -14,7 +14,7 @@
 "connecting-3": {
"id": "# সংযোগ হচ্ছে-3",
"control": "সংযোগ হচ্ছে-3",
-   "title": "I cannot reach X.onion!",
-   "description": "If you cannot reach the onion service 
you desire, make sure that you have entered the 16-character onion address 
correctly: even a small mistake will stop Tor Browser from being able to reach 
the site. If you are still unable to connect to the onion service, please try 
again later. There may be a temporary connection issue, or the site operators 
may have allowed it to go offline without warning.You can 
also ensure that you're able to access other onion services by connecting to http://3g2upl4pq6kufc4m.onion\;>DuckDuckGo's ​Onion Service."
+   "title": "আমি X.onion এ পৌঁছাতে পারছি 
না!",
+   "description": "যদি আপনি পেঁয়াজ 
পরিষেবাতে পৌঁছাতে না পারেন, 
তবে নিশ্চিত করুন যে আপনি 16-অ
ক্ষরের পেঁয়াজের ঠিকানায় সঠ
িকভাবে প্রবেশ করেছেন: এমনকি 
একটি ছোট ভুল টর্ ব্রাউজারটি 
সাইটে পৌঁছাতে সক্ষম হবেনা। 
যদি আপনি এখনও পেঁয়াজ পরিষেবা 
সংযোগ করতে অক্ষম হন, তাহলে পরে 
আবার চেষ্টা করুন। একটি অ
স্থায়ী সংযোগ সমস্যা হতে 
পারে, বা সাইট অপারেটর এটি 
সতর্কবার্তা ছাড়াই অফলাইনে 
যেতে অনুমতি দেওয়া হতে
  পারে। আপনি আপনি DuckDuckGo এর 
পেঁয়াজ পরিষেবা সংযোগ করে অ
ন্য পেঁয়াজ পরিষেবা অ
্যাক্সেস করতে পারবেন তা 
নিশ্চিত করতে পারেন।"
 }
 }

___
tor-commits mailing list
tor-commits@lists.torproject.org
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits