Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions docs/PAYJOIN.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,11 @@ tor_control_host = localhost
# note: port needs to be provided (but is ignored for UNIX socket)
tor_control_port = 9051

# by default, the tor control connection used cookie auth, which assumes
# the tor node to be running on a shared filesystem.
# to authenticate to the tor control port using HashedControlPassword instead:
# tor_control_password=xxx

# the host/port actually serving the hidden service
# (note the *virtual port*, that the client uses,
# is hardcoded to 80):
Expand Down
5 changes: 5 additions & 0 deletions docs/onion-message-channels.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ tor_control_host = localhost
# note: port needs to be provided (but is ignored for UNIX socket)
tor_control_port = 9051

# by default, the tor control connection used cookie auth, which assumes
# the tor node to be running on a shared filesystem.
# to authenticate to the tor control port using HashedControlPassword instead:
# tor_control_password=xxx

# the host/port actually serving the hidden service
# (note the *virtual port*, that the client uses,
# is hardcoded to as per below 'directory node configuration'.
Expand Down
27 changes: 26 additions & 1 deletion docs/tor.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ To use the new onion messaging system (see [here](onion-message-channels.md)) as

<a name="torconfig" />

#### Configuring Tor to setup an onion service
#### Configuring Tor to setup an onion service (local Tor node)

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

Expand Down Expand Up @@ -83,3 +83,28 @@ sudo service tor start
```

Once this is done, you should be able to start the yieldgenerator successfully.

#### Configuring Tor to setup an onion service (remote Tor node)

Cookie authentication assumes the Joinmarket and Tor processes have shared filesystem access to where Tor stores its control cookie.

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:

```
tor --hash-password !CHANGEME!

sudo vim /etc/tor/torrc
```

, and add it to the torrc:

```
ControlPort 9051
HashedControlPassword RESULT_OF_hash-password
```

Then add the same password to your joinmarket configuration:

```
tor_control_password=!CHANGEME!
```
7 changes: 6 additions & 1 deletion scripts/snicker/snicker-server.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,11 +302,16 @@ def start_tor(self):
if not self.local_port:
control_host = jm_single().config.get("PAYJOIN", "tor_control_host")
control_port = int(jm_single().config.get("PAYJOIN", "tor_control_port"))
control_pass = jm_single().config.get("PAYJOIN", "tor_control_password")
if str(control_host).startswith('unix:'):
control_endpoint = UNIXClientEndpoint(reactor, control_host[5:])
else:
control_endpoint = TCP4ClientEndpoint(reactor, control_host, control_port)
d = txtorcon.connect(reactor, control_endpoint)

if control_pass is None or len(str(control_pass)) == 0:
d = txtorcon.connect(reactor, control_endpoint)
else:
d = txtorcon.connect(reactor, control_endpoint, password_function=lambda : control_pass)
d.addCallback(self.create_onion_ep)
d.addErrback(self.setup_failed)
else:
Expand Down
7 changes: 6 additions & 1 deletion src/jmbase/twisted_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ def __init__(self, proto_factory_or_resource, info_callback,
tor_control_port, serving_host, serving_port,
virtual_port=None,
shutdown_callback=None,
tor_control_password=None,
hidden_service_dir=""):
if isinstance(proto_factory_or_resource, Resource):
# TODO bad naming, in this case it doesn't start
Expand All @@ -158,6 +159,7 @@ def __init__(self, proto_factory_or_resource, info_callback,
self.virtual_port = virtual_port
self.tor_control_host = tor_control_host
self.tor_control_port = tor_control_port
self.tor_control_password = tor_control_password
# note that defaults only exist in jmclient
# config object, so no default here:
self.serving_host = serving_host
Expand All @@ -183,7 +185,10 @@ def start_tor(self):
else:
control_endpoint = TCP4ClientEndpoint(reactor,
self.tor_control_host, self.tor_control_port)
d = txtorcon.connect(reactor, control_endpoint)
if self.tor_control_password is None:
d = txtorcon.connect(reactor, control_endpoint)
else:
d = txtorcon.connect(reactor, control_endpoint, password_function=lambda : self.tor_control_password)
Comment on lines +188 to +191
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if self.tor_control_password is None:
d = txtorcon.connect(reactor, control_endpoint)
else:
d = txtorcon.connect(reactor, control_endpoint, password_function=lambda : self.tor_control_password)
password_function = lambda : self.tor_control_password if self.tor_control_password else None
d = txtorcon.connect(reactor, control_endpoint, password_function=password_function)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the former more readable. If maintainer prefer we can go with suggestion.

d.addCallback(self.create_onion_ep)
d.addErrback(self.setup_failed)
# TODO: add errbacks to the next two calls in
Expand Down
1 change: 1 addition & 0 deletions src/jmclient/client_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def connectionMade(self):
netconfig = {"port": 80,
"tor_control_host": jcg("PAYJOIN", "tor_control_host"),
"tor_control_port": jcg("PAYJOIN", "tor_control_port"),
"tor_control_password": jcg("PAYJOIN", "tor_control_password"),
"onion_serving_host": jcg("PAYJOIN", "onion_serving_host"),
"onion_serving_port": jcg("PAYJOIN", "onion_serving_port")}
d = self.callRemote(commands.BIP78ReceiverInit,
Expand Down
10 changes: 10 additions & 0 deletions src/jmclient/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,10 @@ def jm_single() -> AttributeDict:
# tor_control_host = unix:/var/run/tor/control
# note: port needs to be provided (but is ignored for UNIX socket)
tor_control_port = 9051
# by default, the tor control connection used cookie auth, which assumes
# the tor node to be running on a shared filesystem.
# to authenticate to the tor control port using HashedControlPassword instead:
# tor_control_password=xxx

# the host/port actually serving the hidden service
# (note the *virtual port*, that the client uses,
Expand Down Expand Up @@ -450,6 +454,11 @@ def jm_single() -> AttributeDict:
# note: port needs to be provided (but is ignored for UNIX socket)
tor_control_port = 9051

# by default, the tor control connection used cookie auth, which assumes
# the tor node to be running on a shared filesystem.
# to authenticate to the tor control port using HashedControlPassword instead:
# tor_control_password=xxx

# the host/port actually serving the hidden service
# (note the *virtual port*, that the client uses,
# is hardcoded to 80):
Expand Down Expand Up @@ -533,6 +542,7 @@ def get_mchannels(mode: str = "TAKER") -> list:
onion_fields = [("type", str), ("directory_nodes", str), ("regtest_count", str),
("socks5_host", str), ("socks5_port", int),
("tor_control_host", str), ("tor_control_port", int),
("tor_control_password", str),
("onion_serving_host", str), ("onion_serving_port", int),
("hidden_service_dir", str)]

Expand Down
2 changes: 2 additions & 0 deletions src/jmdaemon/daemon_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ def on_BIP78_RECEIVER_INIT(self, netconfig):
self.serving_port = int(netconfig["port"])
self.tor_control_host = netconfig["tor_control_host"]
self.tor_control_port = int(netconfig["tor_control_port"])
self.tor_control_password = netconfig.get("tor_control_password")
self.onion_serving_host=netconfig["onion_serving_host"]
self.onion_serving_port=int(netconfig["onion_serving_port"])
self.bip78_rr = BIP78ReceiverResource(self.info_callback,
Expand All @@ -294,6 +295,7 @@ def on_BIP78_RECEIVER_INIT(self, netconfig):
self.tor_control_port,
self.onion_serving_host,
self.onion_serving_port,
tor_control_password=self.tor_control_password,
shutdown_callback=self.shutdown_callback)
# this call will start bringing up the HS; when it's finished,
# it will fire the `onion_hostname_callback`, or if it fails,
Expand Down
4 changes: 3 additions & 1 deletion src/jmdaemon/onionmc.py
Original file line number Diff line number Diff line change
Expand Up @@ -641,7 +641,8 @@ def __init__(self,
self.serverport = self.hostid
self.tor_control_host = configdata["tor_control_host"]
self.tor_control_port = configdata["tor_control_port"]
self.onion_serving_host=configdata["onion_serving_host"]
self.tor_control_password = configdata.get("tor_control_password")
self.onion_serving_host = configdata["onion_serving_host"]
self.onion_serving = configdata["serving"]
if self.onion_serving:
self.onion_serving_port = configdata["onion_serving_port"]
Expand Down Expand Up @@ -691,6 +692,7 @@ def __init__(self,
self.onion_serving_port,
virtual_port=ONION_VIRTUAL_PORT,
shutdown_callback=self.shutdown_callback,
tor_control_password=self.tor_control_password,
hidden_service_dir=self.hidden_service_dir)
# this call will start bringing up the HS; when it's finished,
# it will fire the `onion_hostname_callback`, or if it fails,
Expand Down
1 change: 1 addition & 0 deletions test/regtest_joinmarket.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ tor_control_host = localhost
# or, to use a UNIX socket
# control_host = unix:/var/run/tor/control
tor_control_port = 9051
tor_control_password = mytorcontrolpassword
# the host/port actually serving the hidden service
# (note the *virtual port*, that the client uses,
# is hardcoded to 80):
Expand Down
Loading