-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtorify.py
117 lines (85 loc) · 3.36 KB
/
torify.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
"""
Redirects all TCP traffic from a python application over TOR.
Usage:
python -mtorify [options] tsttor.py [...]
options:
--proxy PROXY, -p PROXY Where to find the TOR socks5 proxy
--nocheck, -n Skip TOR connection check
Use as module
=============
import torify
torify.set_tor_proxy("127.0.0.1", 9150) # use tor from TorBrowser
torify.use_tor_proxy()
"""
from __future__ import print_function
import socks
import socket
import sys
try:
# first try the python2 module
from urllib2 import urlopen
except:
# then try the python3 module
from urllib.request import urlopen
need_check = True
def set_tor_proxy(addr, port):
socks.setdefaultproxy(socks.SOCKS5, addr, port)
def disable_tor_check():
global need_check
need_check = False
def create_connection(address, timeout=None, source_address=None):
sock = socks.socksocket()
sock.connect(address)
return sock
# todo: implement real socks resolve request.
# for now just fail
def sockshostbyname(host):
raise socket.gaierror(socket.EAI_NONAME, 'nodename nor servname provided, or not known')
def sockshostbyname_ex(host):
raise socket.gaierror(socket.EAI_NONAME, 'nodename nor servname provided, or not known')
def sockshostbyaddr(addr):
raise socket.herror(1, "Unknown host")
def socksgetaddrinfo(*args):
raise socket.gaierror(socket.EAI_NONAME, 'nodename nor servname provided, or not known')
def verify_tor_connection():
""" Verify TOR connection by connecting to check.torproject.org """
content = urlopen('https://check.torproject.org/').read()
# <h1 class="off"> - not using tor
# <h1 class="not"> - using tor without torbrowser
# <h1 class="on"> - using tor with torbrowser
return content.find(b'class="off"')==-1
def use_tor_proxy():
""" Modify the socket mdoule to use the TOR proxy """
if not socks.get_default_proxy():
# when proxy was not explicitly set, use 127.0.0.1:9050
set_tor_proxy('127.0.0.1', 9050)
socket.socket = socks.socksocket
socket.gethostbyname = sockshostbyname
socket.gethostbyaddr = sockshostbyaddr
socket.gethostbyname_ex = sockshostbyname_ex
socket.getaddrinfo = socksgetaddrinfo
socket.create_connection = create_connection
# getfqdn uses gethostbyaddr
# Now all relevant functions are replaced with torified versions
# lets test the connection.
if need_check and not verify_tor_connection():
print("Tor NOT enabled - exiting", file=sys.stderr)
sys.exit(1)
if __name__=="__main__":
# this module was loaded using the `-m` switch, exec the first argument
import argparse
parser = argparse.ArgumentParser(description='python torifier')
parser.add_argument('--proxy', '-p', type=str, help='Where to find the TOR socks5 proxy')
parser.add_argument('--nocheck', '-n', action='store_true', help='Skip TOR connection check')
parser.add_argument('ARGV', type=str, nargs=argparse.REMAINDER, help='The python script with arguments which should be torified')
args = parser.parse_args()
if args.proxy:
addr, port = args.proxy.split(':',1)
set_tor_proxy(addr, int(port))
if args.nocheck:
disable_tor_check()
use_tor_proxy()
sys.argv = args.ARGV
with open(sys.argv[0]) as f:
code = compile(f.read(), sys.argv[0], 'exec')
exec(code, globals(), locals())