[tor-commits] [stem/master] Added downloadable tutorials for tutorial To Russia With Love
atagar at torproject.org
atagar at torproject.org
Mon May 25 17:15:20 UTC 2015
commit 95635c7db39274d1a6f7539e62d915bbe61ebf7f
Author: Sambuddha Basu <sambuddhabasu1 at gmail.com>
Date: Mon May 25 07:19:30 2015 +0400
Added downloadable tutorials for tutorial To Russia With Love
---
docs/_static/example/client_usage_using_pycurl.py | 54 ++++
.../_static/example/client_usage_using_socksipy.py | 25 ++
docs/_static/example/custom_path_selection.py | 79 ++++++
docs/_static/example/reading_twitter.py | 87 +++++++
docs/tutorials/to_russia_with_love.rst | 265 +-------------------
5 files changed, 257 insertions(+), 253 deletions(-)
diff --git a/docs/_static/example/client_usage_using_pycurl.py b/docs/_static/example/client_usage_using_pycurl.py
new file mode 100644
index 0000000..847c106
--- /dev/null
+++ b/docs/_static/example/client_usage_using_pycurl.py
@@ -0,0 +1,54 @@
+import pycurl
+import StringIO
+
+import stem.process
+
+from stem.util import term
+
+SOCKS_PORT = 7000
+
+
+def query(url):
+ """
+ Uses pycurl to fetch a site using the proxy on the SOCKS_PORT.
+ """
+
+ output = StringIO.StringIO()
+
+ query = pycurl.Curl()
+ query.setopt(pycurl.URL, url)
+ query.setopt(pycurl.PROXY, 'localhost')
+ query.setopt(pycurl.PROXYPORT, SOCKS_PORT)
+ query.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5_HOSTNAME)
+ query.setopt(pycurl.WRITEFUNCTION, output.write)
+
+ try:
+ query.perform()
+ return output.getvalue()
+ except pycurl.error as exc:
+ return "Unable to reach %s (%s)" % (url, exc)
+
+
+# Start an instance of Tor configured to only exit through Russia. This prints
+# Tor's bootstrap information as it starts. Note that this likely will not
+# work if you have another Tor instance running.
+
+def print_bootstrap_lines(line):
+ if "Bootstrapped " in line:
+ print term.format(line, term.Color.BLUE)
+
+
+print term.format("Starting Tor:\n", term.Attr.BOLD)
+
+tor_process = stem.process.launch_tor_with_config(
+ config = {
+ 'SocksPort': str(SOCKS_PORT),
+ 'ExitNodes': '{ru}',
+ },
+ init_msg_handler = print_bootstrap_lines,
+)
+
+print term.format("\nChecking our endpoint:\n", term.Attr.BOLD)
+print term.format(query("https://www.atagar.com/echo.php"), term.Color.BLUE)
+
+tor_process.kill() # stops tor
diff --git a/docs/_static/example/client_usage_using_socksipy.py b/docs/_static/example/client_usage_using_socksipy.py
new file mode 100644
index 0000000..c480682
--- /dev/null
+++ b/docs/_static/example/client_usage_using_socksipy.py
@@ -0,0 +1,25 @@
+import socks # SocksiPy module
+import socket
+import urllib
+
+# Set socks proxy and wrap the urllib module
+
+socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', SOCKS_PORT)
+socket.socket = socks.socksocket
+
+# Perform DNS resolution through the socket
+
+def getaddrinfo(*args):
+ return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (args[0], args[1]))]
+
+socket.getaddrinfo = getaddrinfo
+
+def query(url):
+ """
+ Uses urllib to fetch a site using SocksiPy for Tor over the SOCKS_PORT.
+ """
+
+ try:
+ return urllib.urlopen(url).read()
+ except:
+ return "Unable to reach %s" % url
diff --git a/docs/_static/example/custom_path_selection.py b/docs/_static/example/custom_path_selection.py
new file mode 100644
index 0000000..48f6ee7
--- /dev/null
+++ b/docs/_static/example/custom_path_selection.py
@@ -0,0 +1,79 @@
+import StringIO
+import time
+
+import pycurl
+
+import stem.control
+
+# Static exit for us to make 2-hop circuits through. Picking aurora, a
+# particularly beefy one...
+#
+# https://atlas.torproject.org/#details/379FB450010D17078B3766C2273303C358C3A442
+
+EXIT_FINGERPRINT = '379FB450010D17078B3766C2273303C358C3A442'
+
+SOCKS_PORT = 9050
+CONNECTION_TIMEOUT = 30 # timeout before we give up on a circuit
+
+def query(url):
+ """
+ Uses pycurl to fetch a site using the proxy on the SOCKS_PORT.
+ """
+
+ output = StringIO.StringIO()
+
+ query = pycurl.Curl()
+ query.setopt(pycurl.URL, url)
+ query.setopt(pycurl.PROXY, 'localhost')
+ query.setopt(pycurl.PROXYPORT, SOCKS_PORT)
+ query.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5_HOSTNAME)
+ query.setopt(pycurl.CONNECTTIMEOUT, CONNECTION_TIMEOUT)
+ query.setopt(pycurl.WRITEFUNCTION, output.write)
+
+ try:
+ query.perform()
+ return output.getvalue()
+ except pycurl.error as exc:
+ raise ValueError("Unable to reach %s (%s)" % (url, exc))
+
+
+def scan(controller, path):
+ """
+ Fetch check.torproject.org through the given path of relays, providing back
+ the time it took.
+ """
+
+ circuit_id = controller.new_circuit(path, await_build = True)
+
+ def attach_stream(stream):
+ if stream.status == 'NEW':
+ controller.attach_stream(stream.id, circuit_id)
+
+ controller.add_event_listener(attach_stream, stem.control.EventType.STREAM)
+
+ try:
+ controller.set_conf('__LeaveStreamsUnattached', '1') # leave stream management to us
+ start_time = time.time()
+
+ check_page = query('https://check.torproject.org/')
+
+ if 'Congratulations. This browser is configured to use Tor.' not in check_page:
+ raise ValueError("Request didn't have the right content")
+
+ return time.time() - start_time
+ finally:
+ controller.remove_event_listener(attach_stream)
+ controller.reset_conf('__LeaveStreamsUnattached')
+
+
+with stem.control.Controller.from_port() as controller:
+ controller.authenticate()
+
+ relay_fingerprints = [desc.fingerprint for desc in controller.get_network_statuses()]
+
+ for fingerprint in relay_fingerprints:
+ try:
+ time_taken = scan(controller, [fingerprint, EXIT_FINGERPRINT])
+ print '%s => %0.2f seconds' % (fingerprint, time_taken)
+ except Exception as exc:
+ print '%s => %s' % (fingerprint, exc)
diff --git a/docs/_static/example/reading_twitter.py b/docs/_static/example/reading_twitter.py
new file mode 100644
index 0000000..b5dc684
--- /dev/null
+++ b/docs/_static/example/reading_twitter.py
@@ -0,0 +1,87 @@
+import binascii
+import hashlib
+import hmac
+import json
+import socket
+import time
+import urllib
+import urllib2
+
+import socks # SockiPy module
+import stem.process
+
+SOCKS_PORT = 7000
+TWITTER_API_URL = "https://api.twitter.com/1.1/statuses/user_timeline.json"
+CONSUMER_KEY = ""
+CONSUMER_SECRET = ""
+ACCESS_TOKEN = ""
+ACCESS_TOKEN_SECRET = ""
+
+HEADER_AUTH_KEYS = ['oauth_consumer_key', 'oauth_nonce', 'oauth_signature',
+ 'oauth_signature_method', 'oauth_timestamp', 'oauth_token', 'oauth_version']
+
+socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', SOCKS_PORT)
+socket.socket = socks.socksocket
+
+def oauth_signature(key_dict):
+ fin_key = ""
+
+ for key in sorted(key_dict.keys()):
+ fin_key += key + "=" + key_dict[key] + "&"
+
+ fin_key = fin_key[:-1]
+ fin_key = 'GET' + "&" + urllib.quote(TWITTER_API_URL, '') + "&" + urllib.quote(fin_key, '')
+ key = urllib.quote(CONSUMER_SECRET, '') + "&" + urllib.quote(ACCESS_TOKEN_SECRET, '')
+ hashed = hmac.new(key, fin_key, hashlib.sha1)
+ fin_key = binascii.b2a_base64(hashed.digest())[:-1]
+ return urllib.quote(fin_key, '')
+
+def poll_twitter_feed(user_id, tweet_count):
+ """
+ Polls Twitter for the tweets from a given user.
+ """
+
+ key_dict = {
+ 'oauth_consumer_key': urllib.quote(CONSUMER_KEY, ''),
+ 'oauth_nonce': urllib.quote(hashlib.md5(str(time.time())).hexdigest(), ''),
+ 'oauth_signature_method': urllib.quote("HMAC-SHA1", ''),
+ 'oauth_timestamp': urllib.quote(str(int(time.time())), ''),
+ 'oauth_token': urllib.quote(ACCESS_TOKEN, ''),
+ 'oauth_version': urllib.quote('1.0', ''),
+ }
+
+ url_values = {'screen_name': user_id, 'count': str(tweet_count), 'include_rts': '1'}
+
+ for key, value in url_values.items():
+ key_dict[key] = urllib.quote(value, '')
+
+ key_dict['oauth_signature'] = oauth_signature(key_dict)
+
+ header_auth = 'OAuth ' + ', '.join(['%s="%s"' % (key, key_dict[key]) for key in HEADER_AUTH_KEYS])
+
+ data = urllib.urlencode(url_values)
+ api_request = urllib2.Request(TWITTER_API_URL + "?" + data, headers = {'Authorization': header_auth})
+
+ try:
+ api_response = urllib2.urlopen(api_request).read()
+ except:
+ raise IOError("Unable to reach %s" % TWITTER_API_URL)
+
+ return json.loads(api_response)
+
+tor_process = stem.process.launch_tor_with_config(
+ config = {
+ 'SocksPort': str(SOCKS_PORT),
+ 'ExitNodes': '{ru}',
+ },
+)
+
+try:
+ for index, tweet in enumerate(poll_twitter_feed('ioerror', 3)):
+ print "%i. %s" % (index + 1, tweet["created_at"])
+ print tweet["text"]
+ print
+except IOError, exc:
+ print exc
+finally:
+ tor_process.kill() # stops tor
diff --git a/docs/tutorials/to_russia_with_love.rst b/docs/tutorials/to_russia_with_love.rst
index f8bedc6..fc1b4d2 100644
--- a/docs/tutorials/to_russia_with_love.rst
+++ b/docs/tutorials/to_russia_with_love.rst
@@ -51,62 +51,9 @@ be edge cases that expose your real IP. If you have a suggestion for how to
improve this example then please `let me know
<https://www.atagar.com/contact/>`_!
-::
-
- import pycurl
- import StringIO
-
- import stem.process
-
- from stem.util import term
-
- SOCKS_PORT = 7000
-
-
- def query(url):
- """
- Uses pycurl to fetch a site using the proxy on the SOCKS_PORT.
- """
-
- output = StringIO.StringIO()
-
- query = pycurl.Curl()
- query.setopt(pycurl.URL, url)
- query.setopt(pycurl.PROXY, 'localhost')
- query.setopt(pycurl.PROXYPORT, SOCKS_PORT)
- query.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5_HOSTNAME)
- query.setopt(pycurl.WRITEFUNCTION, output.write)
-
- try:
- query.perform()
- return output.getvalue()
- except pycurl.error as exc:
- return "Unable to reach %s (%s)" % (url, exc)
-
-
- # Start an instance of Tor configured to only exit through Russia. This prints
- # Tor's bootstrap information as it starts. Note that this likely will not
- # work if you have another Tor instance running.
-
- def print_bootstrap_lines(line):
- if "Bootstrapped " in line:
- print term.format(line, term.Color.BLUE)
-
-
- print term.format("Starting Tor:\n", term.Attr.BOLD)
-
- tor_process = stem.process.launch_tor_with_config(
- config = {
- 'SocksPort': str(SOCKS_PORT),
- 'ExitNodes': '{ru}',
- },
- init_msg_handler = print_bootstrap_lines,
- )
-
- print term.format("\nChecking our endpoint:\n", term.Attr.BOLD)
- print term.format(query("https://www.atagar.com/echo.php"), term.Color.BLUE)
-
- tor_process.kill() # stops tor
+.. literalinclude:: /_static/example/client_usage_using_pycurl.py
+ :caption: `[Download] <../_static/example/client_usage_using_pycurl.py>`__
+ :language: python
.. image:: /_static/locale_selection_output.png
@@ -121,33 +68,9 @@ connections through Tor, so this'll break our ability to connect to Tor's
control port. To use this approach simply replace the query() function above
with...
-::
-
- import socks # SocksiPy module
- import socket
- import urllib
-
- # Set socks proxy and wrap the urllib module
-
- socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', SOCKS_PORT)
- socket.socket = socks.socksocket
-
- # Perform DNS resolution through the socket
-
- def getaddrinfo(*args):
- return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (args[0], args[1]))]
-
- socket.getaddrinfo = getaddrinfo
-
- def query(url):
- """
- Uses urllib to fetch a site using SocksiPy for Tor over the SOCKS_PORT.
- """
-
- try:
- return urllib.urlopen(url).read()
- except:
- return "Unable to reach %s" % url
+.. literalinclude:: /_static/example/client_usage_using_socksipy.py
+ :caption: `[Download] <../_static/example/client_usage_using_socksipy.py>`__
+ :language: python
.. _reading-twitter:
@@ -160,95 +83,9 @@ Tor. This can be done `using their API
authentication `see their instructions
<https://dev.twitter.com/oauth/overview/application-owner-access-tokens>`_...
-::
-
- import binascii
- import hashlib
- import hmac
- import json
- import socket
- import time
- import urllib
- import urllib2
-
- import socks # SockiPy module
- import stem.process
-
- SOCKS_PORT = 7000
- TWITTER_API_URL = "https://api.twitter.com/1.1/statuses/user_timeline.json"
- CONSUMER_KEY = ""
- CONSUMER_SECRET = ""
- ACCESS_TOKEN = ""
- ACCESS_TOKEN_SECRET = ""
-
- HEADER_AUTH_KEYS = ['oauth_consumer_key', 'oauth_nonce', 'oauth_signature',
- 'oauth_signature_method', 'oauth_timestamp', 'oauth_token', 'oauth_version']
-
- socks.setdefaultproxy(socks.PROXY_TYPE_SOCKS5, '127.0.0.1', SOCKS_PORT)
- socket.socket = socks.socksocket
-
- def oauth_signature(key_dict):
- fin_key = ""
-
- for key in sorted(key_dict.keys()):
- fin_key += key + "=" + key_dict[key] + "&"
-
- fin_key = fin_key[:-1]
- fin_key = 'GET' + "&" + urllib.quote(TWITTER_API_URL, '') + "&" + urllib.quote(fin_key, '')
- key = urllib.quote(CONSUMER_SECRET, '') + "&" + urllib.quote(ACCESS_TOKEN_SECRET, '')
- hashed = hmac.new(key, fin_key, hashlib.sha1)
- fin_key = binascii.b2a_base64(hashed.digest())[:-1]
- return urllib.quote(fin_key, '')
-
- def poll_twitter_feed(user_id, tweet_count):
- """
- Polls Twitter for the tweets from a given user.
- """
-
- key_dict = {
- 'oauth_consumer_key': urllib.quote(CONSUMER_KEY, ''),
- 'oauth_nonce': urllib.quote(hashlib.md5(str(time.time())).hexdigest(), ''),
- 'oauth_signature_method': urllib.quote("HMAC-SHA1", ''),
- 'oauth_timestamp': urllib.quote(str(int(time.time())), ''),
- 'oauth_token': urllib.quote(ACCESS_TOKEN, ''),
- 'oauth_version': urllib.quote('1.0', ''),
- }
-
- url_values = {'screen_name': user_id, 'count': str(tweet_count), 'include_rts': '1'}
-
- for key, value in url_values.items():
- key_dict[key] = urllib.quote(value, '')
-
- key_dict['oauth_signature'] = oauth_signature(key_dict)
-
- header_auth = 'OAuth ' + ', '.join(['%s="%s"' % (key, key_dict[key]) for key in HEADER_AUTH_KEYS])
-
- data = urllib.urlencode(url_values)
- api_request = urllib2.Request(TWITTER_API_URL + "?" + data, headers = {'Authorization': header_auth})
-
- try:
- api_response = urllib2.urlopen(api_request).read()
- except:
- raise IOError("Unable to reach %s" % TWITTER_API_URL)
-
- return json.loads(api_response)
-
- tor_process = stem.process.launch_tor_with_config(
- config = {
- 'SocksPort': str(SOCKS_PORT),
- 'ExitNodes': '{ru}',
- },
- )
-
- try:
- for index, tweet in enumerate(poll_twitter_feed('ioerror', 3)):
- print "%i. %s" % (index + 1, tweet["created_at"])
- print tweet["text"]
- print
- except IOError, exc:
- print exc
- finally:
- tor_process.kill() # stops tor
+.. literalinclude:: /_static/example/reading_twitter.py
+ :caption: `[Download] <../_static/example/reading_twitter.py>`__
+ :language: python
.. image:: /_static/twitter_output.png
@@ -277,87 +114,9 @@ For an example of this lets fetch a site over each relay to determine it's
reachability and speed. **Naturally doing this causes quite a bit of load so
please be careful not to leave this running!**
-::
-
- import StringIO
- import time
-
- import pycurl
-
- import stem.control
-
- # Static exit for us to make 2-hop circuits through. Picking aurora, a
- # particularly beefy one...
- #
- # https://atlas.torproject.org/#details/379FB450010D17078B3766C2273303C358C3A442
-
- EXIT_FINGERPRINT = '379FB450010D17078B3766C2273303C358C3A442'
-
- SOCKS_PORT = 9050
- CONNECTION_TIMEOUT = 30 # timeout before we give up on a circuit
-
- def query(url):
- """
- Uses pycurl to fetch a site using the proxy on the SOCKS_PORT.
- """
-
- output = StringIO.StringIO()
-
- query = pycurl.Curl()
- query.setopt(pycurl.URL, url)
- query.setopt(pycurl.PROXY, 'localhost')
- query.setopt(pycurl.PROXYPORT, SOCKS_PORT)
- query.setopt(pycurl.PROXYTYPE, pycurl.PROXYTYPE_SOCKS5_HOSTNAME)
- query.setopt(pycurl.CONNECTTIMEOUT, CONNECTION_TIMEOUT)
- query.setopt(pycurl.WRITEFUNCTION, output.write)
-
- try:
- query.perform()
- return output.getvalue()
- except pycurl.error as exc:
- raise ValueError("Unable to reach %s (%s)" % (url, exc))
-
-
- def scan(controller, path):
- """
- Fetch check.torproject.org through the given path of relays, providing back
- the time it took.
- """
-
- circuit_id = controller.new_circuit(path, await_build = True)
-
- def attach_stream(stream):
- if stream.status == 'NEW':
- controller.attach_stream(stream.id, circuit_id)
-
- controller.add_event_listener(attach_stream, stem.control.EventType.STREAM)
-
- try:
- controller.set_conf('__LeaveStreamsUnattached', '1') # leave stream management to us
- start_time = time.time()
-
- check_page = query('https://check.torproject.org/')
-
- if 'Congratulations. This browser is configured to use Tor.' not in check_page:
- raise ValueError("Request didn't have the right content")
-
- return time.time() - start_time
- finally:
- controller.remove_event_listener(attach_stream)
- controller.reset_conf('__LeaveStreamsUnattached')
-
-
- with stem.control.Controller.from_port() as controller:
- controller.authenticate()
-
- relay_fingerprints = [desc.fingerprint for desc in controller.get_network_statuses()]
-
- for fingerprint in relay_fingerprints:
- try:
- time_taken = scan(controller, [fingerprint, EXIT_FINGERPRINT])
- print '%s => %0.2f seconds' % (fingerprint, time_taken)
- except Exception as exc:
- print '%s => %s' % (fingerprint, exc)
+.. literalinclude:: /_static/example/custom_path_selection.py
+ :caption: `[Download] <../_static/example/custom_path_selection.py>`__
+ :language: python
::
More information about the tor-commits
mailing list