Skip to content

Commit e048dab

Browse files
author
3np
committed
tor: allow authenticating to control port using hashedpassword auth
- add configuration for tor_control_hashedpassword for onion services
1 parent 94660e7 commit e048dab

File tree

9 files changed

+59
-4
lines changed

9 files changed

+59
-4
lines changed

docs/PAYJOIN.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ tor_control_host = localhost
216216
# note: port needs to be provided (but is ignored for UNIX socket)
217217
tor_control_port = 9051
218218
219+
# by default, the tor control connection used cookie auth, which assumes
220+
# the tor node to be running on a shared filesystem.
221+
# to authenticate to the tor control port using HashedControlPassword instead:
222+
#tor_control_hashedpassword=xxx
223+
219224
# the host/port actually serving the hidden service
220225
# (note the *virtual port*, that the client uses,
221226
# is hardcoded to 80):

docs/onion-message-channels.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ tor_control_host = localhost
4646
# note: port needs to be provided (but is ignored for UNIX socket)
4747
tor_control_port = 9051
4848

49+
# by default, the tor control connection used cookie auth, which assumes
50+
# the tor node to be running on a shared filesystem.
51+
# to authenticate to the tor control port using HashedControlPassword instead:
52+
#tor_control_hashedpassword=xxx
53+
4954
# the host/port actually serving the hidden service
5055
# (note the *virtual port*, that the client uses,
5156
# is hardcoded to as per below 'directory node configuration'.

docs/tor.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ To use the new onion messaging system (see [here](onion-message-channels.md)) as
3838

3939
<a name="torconfig" />
4040

41-
#### Configuring Tor to setup an onion service
41+
#### Configuring Tor to setup an onion service (local Tor node)
4242

4343
(These steps were prepared using Ubuntu; you may have to adjust for your distro).
4444

@@ -83,3 +83,22 @@ sudo service tor start
8383
```
8484

8585
Once this is done, you should be able to start the yieldgenerator successfully.
86+
87+
#### Configuring Tor to setup an onion service (remote Tor node)
88+
89+
Cookie authentication assumes the Joinmarket and Tor processes have shared filesystem access to where Tor stores its control cookie.
90+
91+
If this is not possible or desired, for example if Tor is running on another machine, you can instead use a password. On the tor node, hash the password:
92+
93+
```
94+
tor --hash-password !CHANGEME!
95+
96+
sudo vim /etc/tor/torrc
97+
```
98+
99+
, and add it to the torrc:
100+
101+
```
102+
ControlPort 9051
103+
HashedControlPassword RESULT_OF_hash-password
104+
```

scripts/snicker/snicker-server.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,17 @@ def start_tor(self):
302302
if not self.local_port:
303303
control_host = jm_single().config.get("PAYJOIN", "tor_control_host")
304304
control_port = int(jm_single().config.get("PAYJOIN", "tor_control_port"))
305+
control_hashedpass = jm_single().config.get("PAYJOIN", "tor_control_hashedpasword")
305306
if str(control_host).startswith('unix:'):
306307
control_endpoint = UNIXClientEndpoint(reactor, control_host[5:])
307308
else:
308309
control_endpoint = TCP4ClientEndpoint(reactor, control_host, control_port)
309-
d = txtorcon.connect(reactor, control_endpoint)
310+
311+
password_cb = None
312+
if not control_hashedpass is None and len(str(control_hashedpass)) > 0:
313+
password_cb = lambda : control_hashedpass
314+
315+
d = txtorcon.connect(reactor, control_endpoint, password_function=password_cb)
310316
d.addCallback(self.create_onion_ep)
311317
d.addErrback(self.setup_failed)
312318
else:

src/jmbase/twisted_utils.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ def __init__(self, proto_factory_or_resource, info_callback,
137137
tor_control_port, serving_host, serving_port,
138138
virtual_port=None,
139139
shutdown_callback=None,
140+
tor_control_hashedpassword=None,
140141
hidden_service_dir=""):
141142
if isinstance(proto_factory_or_resource, Resource):
142143
# TODO bad naming, in this case it doesn't start
@@ -158,6 +159,7 @@ def __init__(self, proto_factory_or_resource, info_callback,
158159
self.virtual_port = virtual_port
159160
self.tor_control_host = tor_control_host
160161
self.tor_control_port = tor_control_port
162+
self.tor_control_hashedpassword = tor_control_hashedpassword
161163
# note that defaults only exist in jmclient
162164
# config object, so no default here:
163165
self.serving_host = serving_host
@@ -183,7 +185,10 @@ def start_tor(self):
183185
else:
184186
control_endpoint = TCP4ClientEndpoint(reactor,
185187
self.tor_control_host, self.tor_control_port)
186-
d = txtorcon.connect(reactor, control_endpoint)
188+
if self.tor_control_hashedpassword is None:
189+
d = txtorcon.connect(reactor, control_endpoint)
190+
else:
191+
d = txtorcon.connect(reactor, control_endpoint, password_function=lambda : self.tor_control_hashedpassword)
187192
d.addCallback(self.create_onion_ep)
188193
d.addErrback(self.setup_failed)
189194
# TODO: add errbacks to the next two calls in

src/jmclient/client_protocol.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ def connectionMade(self):
8787
netconfig = {"port": 80,
8888
"tor_control_host": jcg("PAYJOIN", "tor_control_host"),
8989
"tor_control_port": jcg("PAYJOIN", "tor_control_port"),
90+
"tor_control_hashedpassword": jcg("PAYJOIN", "tor_control_hashedpassword"),
9091
"onion_serving_host": jcg("PAYJOIN", "onion_serving_host"),
9192
"onion_serving_port": jcg("PAYJOIN", "onion_serving_port")}
9293
d = self.callRemote(commands.BIP78ReceiverInit,

src/jmclient/configure.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ def jm_single() -> AttributeDict:
158158
# tor_control_host = unix:/var/run/tor/control
159159
# note: port needs to be provided (but is ignored for UNIX socket)
160160
tor_control_port = 9051
161+
# by default, the tor control connection used cookie auth, which assumes
162+
# the tor node to be running on a shared filesystem.
163+
# to authenticate to the tor control port using HashedControlPassword instead:
164+
#tor_control_hashedpassword=xxx
161165
162166
# the host/port actually serving the hidden service
163167
# (note the *virtual port*, that the client uses,
@@ -450,6 +454,11 @@ def jm_single() -> AttributeDict:
450454
# note: port needs to be provided (but is ignored for UNIX socket)
451455
tor_control_port = 9051
452456
457+
# by default, the tor control connection used cookie auth, which assumes
458+
# the tor node to be running on a shared filesystem.
459+
# to authenticate to the tor control port using HashedControlPassword instead:
460+
#tor_control_hashedpassword=xxx
461+
453462
# the host/port actually serving the hidden service
454463
# (note the *virtual port*, that the client uses,
455464
# is hardcoded to 80):
@@ -533,6 +542,7 @@ def get_mchannels(mode: str = "TAKER") -> list:
533542
onion_fields = [("type", str), ("directory_nodes", str), ("regtest_count", str),
534543
("socks5_host", str), ("socks5_port", int),
535544
("tor_control_host", str), ("tor_control_port", int),
545+
("tor_control_hashedpassword", str),
536546
("onion_serving_host", str), ("onion_serving_port", int),
537547
("hidden_service_dir", str)]
538548

src/jmdaemon/daemon_protocol.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ def on_BIP78_RECEIVER_INIT(self, netconfig):
281281
self.serving_port = int(netconfig["port"])
282282
self.tor_control_host = netconfig["tor_control_host"]
283283
self.tor_control_port = int(netconfig["tor_control_port"])
284+
self.tor_control_hashedpassword = netconfig["tor_control_hashedpassword"]
284285
self.onion_serving_host=netconfig["onion_serving_host"]
285286
self.onion_serving_port=int(netconfig["onion_serving_port"])
286287
self.bip78_rr = BIP78ReceiverResource(self.info_callback,
@@ -294,6 +295,7 @@ def on_BIP78_RECEIVER_INIT(self, netconfig):
294295
self.tor_control_port,
295296
self.onion_serving_host,
296297
self.onion_serving_port,
298+
tor_control_hashedpassword=self.tor_control_hashedpassword,
297299
shutdown_callback=self.shutdown_callback)
298300
# this call will start bringing up the HS; when it's finished,
299301
# it will fire the `onion_hostname_callback`, or if it fails,

src/jmdaemon/onionmc.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -641,7 +641,8 @@ def __init__(self,
641641
self.serverport = self.hostid
642642
self.tor_control_host = configdata["tor_control_host"]
643643
self.tor_control_port = configdata["tor_control_port"]
644-
self.onion_serving_host=configdata["onion_serving_host"]
644+
self.tor_control_hashedpassword = configdata["tor_control_hashedpassword"]
645+
self.onion_serving_host = configdata["onion_serving_host"]
645646
self.onion_serving = configdata["serving"]
646647
if self.onion_serving:
647648
self.onion_serving_port = configdata["onion_serving_port"]
@@ -691,6 +692,7 @@ def __init__(self,
691692
self.onion_serving_port,
692693
virtual_port=ONION_VIRTUAL_PORT,
693694
shutdown_callback=self.shutdown_callback,
695+
tor_control_hashedpassword=self.tor_control_hashedpassword,
694696
hidden_service_dir=self.hidden_service_dir)
695697
# this call will start bringing up the HS; when it's finished,
696698
# it will fire the `onion_hostname_callback`, or if it fails,

0 commit comments

Comments
 (0)