forked from Coldcard/ckbunker
-
Notifications
You must be signed in to change notification settings - Fork 0
/
torsion.py
151 lines (106 loc) · 4.68 KB
/
torsion.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/env python
#
# Interface to STEM and from that to Tord and the Tor network.
#
# Refs:
# - <https://stem.torproject.org/tutorials/over_the_river.html#ephemeral-hidden-services>
#
import logging, asyncio
from utils import json_loads, json_dumps, Singleton
from concurrent.futures import ThreadPoolExecutor
from persist import settings
from status import STATUS
logging.getLogger(__name__).addHandler(logging.NullHandler())
executor = ThreadPoolExecutor(max_workers=10)
class TorViaStem(metaclass=Singleton):
def __init__(self):
self.controller = None
self.service = None
async def startup(self):
# just test if we can see tord
await self.connect(raise_on_error=False)
def get_current_addr(self):
# return onion address we are currently on, or None
if not self.service:
return None
return self.service.service_id + '.onion'
async def connect(self, raise_on_error=True):
from stem.connection import connect
if self.controller:
return self.controller
def doit():
self.controller = connect(control_port=('127.0.0.1', settings.TORD_PORT))
if self.controller:
logging.info("Tord version: " + str(self.controller.get_version()))
else:
logging.error("Unable to connect to local 'tord' server")
if raise_on_error:
raise RuntimeError("No local 'tord' server")
return self.controller
loop = asyncio.get_running_loop()
rv = await loop.run_in_executor(executor, doit)
STATUS.tord_good = bool(rv)
STATUS.notify_watchers()
async def pick_onion_addr(self):
c = await self.connect()
def doit():
# let Tor pick the key, since they don't document their tricky stuff
s = self.controller.create_ephemeral_hidden_service({80: 1},
detached=False,
await_publication=False, key_content='ED25519-V3')
rv = (s.service_id+'.onion', s.private_key)
# kill it immediately
self.controller.remove_ephemeral_hidden_service(s.service_id)
return rv
loop = asyncio.get_running_loop()
return await loop.run_in_executor(executor, doit)
async def stop_tunnel(self):
# hang up if running
if not self.service:
return
def doit():
if self.service:
logging.info(f"Disconnecting previous service at: {self.service.service_id}.onion")
self.controller.remove_ephemeral_hidden_service(self.service.service_id)
self.service = None
STATUS.onion_addr = None
STATUS.notify_watchers()
loop = asyncio.get_running_loop()
return await loop.run_in_executor(executor, doit)
async def start_tunnel(self):
from persist import BP, settings
c = await self.connect()
def doit():
if self.service:
logging.info(f"Disconnecting previous service at: {self.service.service_id}.onion")
self.controller.remove_ephemeral_hidden_service(self.service.service_id)
self.service = None
# give Tor the key from earlier run
k = BP['onion_pk']
s = self.controller.create_ephemeral_hidden_service({80: settings.PORT_NUMBER},
detached=False, discard_key=True,
await_publication=True, key_type='ED25519-V3', key_content=k)
addr = s.service_id+'.onion'
assert addr == BP['onion_addr'], f"Mismatch, got: {addr} not {BP.onion_addr} expected"
self.service = s
return addr
loop = asyncio.get_running_loop()
addr = await loop.run_in_executor(executor, doit)
STATUS.onion_addr = addr
STATUS.notify_watchers()
TOR = TorViaStem()
if __name__ == '__main__':
controller = connect()
if not controller:
sys.exit(1) # unable to get a connection
print('Your tord is version: %s' % controller.get_version())
#d = controller.get_hidden_service_descriptor('explorernuoc63nb.onion')
d = controller.get_hidden_service_descriptor('explorerzydxu5ecjrkwceayqybizmpjjznk5izmitf2modhcusuqlid.onion')
print("obj = %r" % d)
print("pubkey = %r" % d.permanent_key)
print("published = %r" % d.published)
service = controller.create_ephemeral_hidden_service({80: 5000}, await_publication = True, key_content = 'ED25519-V3')
print("Started a new hidden service with the address of %s.onion" % service.service_id)
print('%s %s' % (service.private_key_type, service.private_key))
controller.close()
# EOF