Set trusted-daemon for XMR node in basicswap.json

basicswap-prepare will set trusted_daemon true if the daemon host address is a local ip address else false.
Override with --trustremotenode
--trustremotenode can be used with --enabletor
2024-05-20_merge
tecnovert 11 months ago
parent a5c3534c19
commit 5ceaab57d1
  1. 17
      basicswap/util/network.py
  2. 19
      bin/basicswap_prepare.py
  3. 8
      bin/basicswap_run.py
  4. 13
      tests/basicswap/test_other.py

@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2024 tecnovert
# Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php.
import ipaddress
def is_private_ip_address(addr: str):
# Will return false for all URLs
if addr == 'localhost':
return True
try:
return ipaddress.ip_address(addr).is_private
except Exception:
return False

@ -34,6 +34,7 @@ from basicswap.basicswap import BasicSwap
from basicswap.chainparams import Coins from basicswap.chainparams import Coins
from basicswap.ui.util import getCoinName from basicswap.ui.util import getCoinName
from basicswap.util import toBool from basicswap.util import toBool
from basicswap.util.network import is_private_ip_address
from basicswap.util.rfc2440 import rfc2440_hash_password from basicswap.util.rfc2440 import rfc2440_hash_password
from basicswap.contrib.rpcauth import generate_salt, password_to_hmac from basicswap.contrib.rpcauth import generate_salt, password_to_hmac
from bin.basicswap_run import startDaemon, startXmrWalletDaemon from bin.basicswap_run import startDaemon, startXmrWalletDaemon
@ -822,7 +823,7 @@ def prepareDataDir(coin, settings, chain, particl_mnemonic, extra_opts={}):
if extra_opts.get('use_containers', False) is True: if extra_opts.get('use_containers', False) is True:
fp.write('daemon-address={}:{}\n'.format(core_settings['rpchost'], core_settings['rpcport'])) fp.write('daemon-address={}:{}\n'.format(core_settings['rpchost'], core_settings['rpcport']))
config_datadir = '/data' config_datadir = '/data'
fp.write('untrusted-daemon=1\n')
fp.write('no-dns=1\n') fp.write('no-dns=1\n')
fp.write('rpc-bind-port={}\n'.format(core_settings['walletrpcport'])) fp.write('rpc-bind-port={}\n'.format(core_settings['walletrpcport']))
fp.write('rpc-bind-ip={}\n'.format(COINS_RPCBIND_IP)) fp.write('rpc-bind-ip={}\n'.format(COINS_RPCBIND_IP))
@ -962,7 +963,7 @@ def addTorSettings(settings, tor_control_password):
settings['tor_control_port'] = TOR_CONTROL_PORT settings['tor_control_port'] = TOR_CONTROL_PORT
def modify_tor_config(settings, coin, tor_control_password=None, enable=False): def modify_tor_config(settings, coin, tor_control_password=None, enable=False, extra_opts={}):
coin_settings = settings['chainclients'][coin] coin_settings = settings['chainclients'][coin]
data_dir = coin_settings['datadir'] data_dir = coin_settings['datadir']
@ -1012,6 +1013,8 @@ def modify_tor_config(settings, coin, tor_control_password=None, enable=False):
if not coin_settings['manage_daemon']: if not coin_settings['manage_daemon']:
fp.write(f'proxy={TOR_PROXY_HOST}:{TOR_PROXY_PORT}\n') fp.write(f'proxy={TOR_PROXY_HOST}:{TOR_PROXY_PORT}\n')
fp.write('daemon-ssl-allow-any-cert=1\n') fp.write('daemon-ssl-allow-any-cert=1\n')
coin_settings['trusted_daemon'] = extra_opts.get('trust_remote_node', is_private_ip_address(coin_settings['rpchost']))
return return
config_path = os.path.join(data_dir, coin + '.conf') config_path = os.path.join(data_dir, coin + '.conf')
@ -1081,6 +1084,7 @@ def printHelp():
print('--htmlhost= Interface to host html server on, default:127.0.0.1.') print('--htmlhost= Interface to host html server on, default:127.0.0.1.')
print('--wshost= Interface to host websocket server on, disable by setting to "none", default:127.0.0.1.') print('--wshost= Interface to host websocket server on, disable by setting to "none", default:127.0.0.1.')
print('--xmrrestoreheight=n Block height to restore Monero wallet from, default:{}.'.format(DEFAULT_XMR_RESTORE_HEIGHT)) print('--xmrrestoreheight=n Block height to restore Monero wallet from, default:{}.'.format(DEFAULT_XMR_RESTORE_HEIGHT))
print('--trustremotenode Set trusted-daemon for XMR, default is true for private ip addresses else false')
print('--noextractover Prevent extracting cores if files exist. Speeds up tests') print('--noextractover Prevent extracting cores if files exist. Speeds up tests')
print('--usetorproxy Use TOR proxy during setup. Note that some download links may be inaccessible over TOR.') print('--usetorproxy Use TOR proxy during setup. Note that some download links may be inaccessible over TOR.')
print('--notorproxy Force usetorproxy off, usetorproxy is automatically set when tor is enabled') print('--notorproxy Force usetorproxy off, usetorproxy is automatically set when tor is enabled')
@ -1370,6 +1374,9 @@ def main():
if name == 'skipbtcfastsyncchecks': if name == 'skipbtcfastsyncchecks':
extra_opts['check_btc_fastsync'] = False extra_opts['check_btc_fastsync'] = False
continue continue
if name == 'trustremotenode':
extra_opts['trust_remote_node'] = True
continue
if name == 'initwalletsonly': if name == 'initwalletsonly':
initwalletsonly = True initwalletsonly = True
continue continue
@ -1419,6 +1426,9 @@ def main():
if name == 'keysdirpath': if name == 'keysdirpath':
extra_opts['keysdirpath'] = os.path.expanduser(s[1].strip('"')) extra_opts['keysdirpath'] = os.path.expanduser(s[1].strip('"'))
continue continue
if name == 'trustremotenode':
extra_opts['trust_remote_node'] = toBool(s[1])
continue
exitWithError('Unknown argument {}'.format(v)) exitWithError('Unknown argument {}'.format(v))
@ -1563,6 +1573,7 @@ def main():
'zmqport': BASE_XMR_ZMQ_PORT + port_offset, 'zmqport': BASE_XMR_ZMQ_PORT + port_offset,
'walletrpcport': BASE_XMR_WALLET_PORT + port_offset, 'walletrpcport': BASE_XMR_WALLET_PORT + port_offset,
'rpchost': XMR_RPC_HOST, 'rpchost': XMR_RPC_HOST,
'trusted_daemon': extra_opts.get('trust_remote_node', is_private_ip_address(XMR_RPC_HOST)),
'walletrpchost': XMR_WALLET_RPC_HOST, 'walletrpchost': XMR_WALLET_RPC_HOST,
'walletrpcuser': XMR_WALLET_RPC_USER, 'walletrpcuser': XMR_WALLET_RPC_USER,
'walletrpcpassword': XMR_WALLET_RPC_PWD, 'walletrpcpassword': XMR_WALLET_RPC_PWD,
@ -1692,7 +1703,7 @@ def main():
addTorSettings(settings, tor_control_password) addTorSettings(settings, tor_control_password)
for coin in settings['chainclients']: for coin in settings['chainclients']:
modify_tor_config(settings, coin, tor_control_password, enable=True) modify_tor_config(settings, coin, tor_control_password, enable=True, extra_opts=extra_opts)
with open(config_path, 'w') as fp: with open(config_path, 'w') as fp:
json.dump(settings, fp, indent=4) json.dump(settings, fp, indent=4)
@ -1705,7 +1716,7 @@ def main():
settings = load_config(config_path) settings = load_config(config_path)
settings['use_tor'] = False settings['use_tor'] = False
for coin in settings['chainclients']: for coin in settings['chainclients']:
modify_tor_config(settings, coin, tor_control_password=None, enable=False) modify_tor_config(settings, coin, tor_control_password=None, enable=False, extra_opts=extra_opts)
with open(config_path, 'w') as fp: with open(config_path, 'w') as fp:
json.dump(settings, fp, indent=4) json.dump(settings, fp, indent=4)

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2019-2023 tecnovert # Copyright (c) 2019-2024 tecnovert
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php. # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@ -176,13 +176,17 @@ def runClient(fp, data_dir, chain, start_only_coins):
if v['manage_wallet_daemon'] is True: if v['manage_wallet_daemon'] is True:
swap_client.log.info(f'Starting {display_name} wallet daemon') swap_client.log.info(f'Starting {display_name} wallet daemon')
daemon_addr = '{}:{}'.format(v['rpchost'], v['rpcport']) daemon_addr = '{}:{}'.format(v['rpchost'], v['rpcport'])
swap_client.log.info('daemon-address: {}'.format(daemon_addr))
trusted_daemon: bool = v.get('trusted_daemon', False)
swap_client.log.info('daemon-address: {} ({})'.format(daemon_addr, 'trusted' if trusted_daemon else 'untrusted'))
opts = ['--daemon-address', daemon_addr, ] opts = ['--daemon-address', daemon_addr, ]
daemon_rpcuser = v.get('rpcuser', '') daemon_rpcuser = v.get('rpcuser', '')
daemon_rpcpass = v.get('rpcpassword', '') daemon_rpcpass = v.get('rpcpassword', '')
if daemon_rpcuser != '': if daemon_rpcuser != '':
opts.append('--daemon-login') opts.append('--daemon-login')
opts.append(daemon_rpcuser + ':' + daemon_rpcpass) opts.append(daemon_rpcuser + ':' + daemon_rpcpass)
opts.append('--trusted-daemon' if trusted_daemon else '--untrusted-daemon')
filename = 'monero-wallet-rpc' + ('.exe' if os.name == 'nt' else '') filename = 'monero-wallet-rpc' + ('.exe' if os.name == 'nt' else '')
daemons.append(startXmrWalletDaemon(v['datadir'], v['bindir'], filename, opts)) daemons.append(startXmrWalletDaemon(v['datadir'], v['bindir'], filename, opts))
pid = daemons[-1].pid pid = daemons[-1].pid

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (c) 2019-2023 tecnovert # Copyright (c) 2019-2024 tecnovert
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE or http://www.opensource.org/licenses/mit-license.php. # file LICENSE or http://www.opensource.org/licenses/mit-license.php.
@ -23,6 +23,7 @@ from coincurve.keys import (
from basicswap.util import i2b, h2b from basicswap.util import i2b, h2b
from basicswap.util.crypto import ripemd160, hash160 from basicswap.util.crypto import ripemd160, hash160
from basicswap.util.network import is_private_ip_address
from basicswap.util.rfc2440 import rfc2440_hash_password from basicswap.util.rfc2440 import rfc2440_hash_password
from basicswap.interface.btc import BTCInterface from basicswap.interface.btc import BTCInterface
from basicswap.interface.xmr import XMRInterface from basicswap.interface.xmr import XMRInterface
@ -336,6 +337,16 @@ class Test(unittest.TestCase):
assert (msg_buf_v2.protocol_version == 2) assert (msg_buf_v2.protocol_version == 2)
def test_is_private_ip_address(self):
assert (is_private_ip_address('localhost'))
assert (is_private_ip_address('127.0.0.1'))
assert (is_private_ip_address('10.0.0.0'))
assert (is_private_ip_address('172.16.0.0'))
assert (is_private_ip_address('192.168.0.0'))
assert (is_private_ip_address('20.87.245.0') is False)
assert (is_private_ip_address('particl.io') is False)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()

Loading…
Cancel
Save