Skip to content
This repository has been archived by the owner on May 13, 2022. It is now read-only.

Obfuscate maker bot identities #422

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
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
7 changes: 7 additions & 0 deletions joinmarket/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,17 @@ def jm_single():
socks5_port = 9050
#for tor
#host = 6dvj6v5imhny3anf.onion
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is the onion host gone? I think this is a mistake.

Copy link
Author

Choose a reason for hiding this comment

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

Using hidserv publicly reveals the fact you're using tor, plus makes your bot unstable. Use HS only on irc networks which don't allow direct tor connections. Opionated I know, I'll revert this if you strongly disagree.

Copy link
Author

Choose a reason for hiding this comment

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

Made check for .onion when newnym is used (and bail on it).

#for switching nyms between reconnects
#newnym = true
#newnym_delay = 60
#tor_ctrl_host = localhost
#tor_ctrl_port = 9051
#tor_ctrl_pass =
#port = 6697
#usessl = true
#socks5 = true
maker_timeout_sec = 30
reconnect_delay = 30

[POLICY]
# for dust sweeping, try merge_algorithm = gradual
Expand Down
42 changes: 40 additions & 2 deletions joinmarket/irc.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import time
import Queue

from ConfigParser import NoOptionError
from joinmarket.configure import jm_single, get_config_irc_channel
from joinmarket.message_channel import MessageChannel, CJPeerError
from joinmarket.enc_wrapper import encrypt_encode, decode_decrypt
Expand Down Expand Up @@ -497,8 +498,9 @@ def __handle_line(self, line):
if self.on_nick_leave:
self.on_nick_leave(nick)
elif _chunks[1] == '433': # nick in use
# self.nick = random_nick()
self.nick += '_' # helps keep identity constant if just _ added
if self.newnyms:
self.nick = random_nick()
self.send_raw('NICK ' + self.nick)
if self.password:
if _chunks[1] == 'CAP':
Expand Down Expand Up @@ -583,13 +585,43 @@ def __init__(self,
self.socks5_port = int(config.get("MESSAGING", "socks5_port"))
self.channel = get_config_irc_channel()
self.userrealname = (username, realname)
self.reconnect_delay = 30
self.newnyms = False
try:
self.reconnect_delay = int(config.get("MESSAGING", "reconnect_delay"))
self.newnyms = (config.get("MESSAGING", "newnym").lower() == 'true')
self.tor_ctrl_host = config.get("MESSAGING", "tor_ctrl_host")
self.tor_ctrl_port = int(config.get("MESSAGING", "tor_ctrl_port"))
self.tor_ctrl_pass = config.get("MESSAGING", "tor_ctrl_pass")
self.newnym_delay = int(config.get("MESSAGING", "newnym_delay"))
except NoOptionError as ex:
log.debug('The following newnym option is missing:')
log.debug(ex)
log.debug('.. disabling the feature.')
self.newnyms = False

if self.newnyms and self.serverport[0].lower().endswith('.onion'):
raise Exception("you can't use newnym=true with host=something.onion")

if password and len(password) == 0:
password = None
self.given_password = password
self.pingQ = Queue.Queue()
self.throttleQ = Queue.Queue()
self.obQ = Queue.Queue()

def newnym(self):
ctrl = socket.create_connection((self.tor_ctrl_host, self.tor_ctrl_port))
ctrl.send('AUTHENTICATE "%s"\r\n'%self.tor_ctrl_pass)
resp = ctrl.recv(1024)
if resp.startswith('250'):
ctrl.send("signal NEWNYM\r\n")
if resp.startswith('250'):
ctrl.close()
return
ctrl.close()
raise IOError("newnym failed "+resp)

def run(self):
self.waiting = {}
self.built_privmsg = {}
Expand All @@ -604,6 +636,10 @@ def run(self):
try:
config = jm_single().config
log.debug('connecting')
if self.newnyms:
log.debug("Grabbing new Tor identity")
self.newnym()
self.nick = random_nick()
if config.get("MESSAGING", "socks5").lower() == 'true':
log.debug("Using socks5 proxy %s:%d" %
(self.socks5_host, self.socks5_port))
Expand Down Expand Up @@ -649,6 +685,8 @@ def run(self):
self.on_disconnect()
log.debug('disconnected irc')
if not self.give_up:
time.sleep(30)
time.sleep(self.reconnect_delay)
if self.newnyms:
time.sleep(random.randint(0,self.newnym_delay))
log.debug('ending irc')
self.give_up = True
5 changes: 4 additions & 1 deletion joinmarket/maker.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ def __init__(self, msgchan, wallet):
self.active_orders = {}
self.wallet = wallet
self.nextoid = -1
self.orderlist = self.create_my_orders()
if not self.msgchan.newnyms:
self.orderlist = self.create_my_orders()
Copy link
Collaborator

Choose a reason for hiding this comment

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

if create_my_orders() is now called in on_welcome() then there's no need to have it here too

Copy link
Author

Choose a reason for hiding this comment

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

This is on purpose - it's called in on_welcome only when newnyms is enabled. The reasoning is that custom maker scripts might not expect this, so when newnyms iss disabled, it falls back to the original order (create orders on instantiation).

self.wallet_unspent_lock = threading.Lock()

def get_crypto_box_from_nick(self, nick):
Expand Down Expand Up @@ -265,6 +266,8 @@ def on_push_tx(self, nick, txhex):
self.msgchan.send_error(nick, 'Unable to push tx')

def on_welcome(self):
if self.msgchan.newnyms:
self.orderlist = self.create_my_orders()
self.msgchan.announce_orders(self.orderlist)
self.active_orders = {}

Expand Down
2 changes: 2 additions & 0 deletions joinmarket/message_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ def __init__(self):
self.on_seen_auth = None
self.on_seen_tx = None
self.on_push_tx = None
# chan-specific attributes
self.newnyms = False

def run(self):
pass
Expand Down