From 39e1eb7a8471df063ec69aca49d5fa5121048530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sa=C5=82aban?= Date: Sun, 29 Dec 2019 23:16:22 +0100 Subject: [PATCH] Add proxy and describe how to use TOR, close #55 --- docs/source/daemon.rst | 17 +++++++++++++++++ monero/backends/jsonrpc.py | 8 +++++--- utils/daemoninfo.py | 3 ++- utils/pushtx.py | 4 +++- utils/transfer.py | 2 +- 5 files changed, 28 insertions(+), 6 deletions(-) diff --git a/docs/source/daemon.rst b/docs/source/daemon.rst index 4ffc698..1cf3df9 100644 --- a/docs/source/daemon.rst +++ b/docs/source/daemon.rst @@ -17,6 +17,23 @@ wallet, the only available backend is JSON RPC. Also, the ``info()`` method will return a dictionary with details about the current daemon status. +Connecting via proxy (or TOR) +----------------------------- + +The backend also accepts optional ``proxy_url`` keyword. A prime example of use is to route +your traffic via TOR: + +.. code-block:: python + + In [3]: daemon = Daemon(JSONRPCDaemon(host='xmrag4hf5xlabmob.onion', proxy_url='socks5h://127.0.0.1:9050')) + + In [4]: daemon.height() + Out[4]: 1999790 + +Please refer to the docs of underlying `requests`_ library for more info on proxies. + +.. _`requests`: http://docs.python-requests.org/ + Sending prepared transactions ----------------------------- diff --git a/monero/backends/jsonrpc.py b/monero/backends/jsonrpc.py index 7c86b57..631ff14 100644 --- a/monero/backends/jsonrpc.py +++ b/monero/backends/jsonrpc.py @@ -24,9 +24,10 @@ class JSONRPCDaemon(object): :param path: path for JSON RPC requests (should not be changed) :param timeout: request timeout :param verify_ssl_certs: verify SSL certificates when connecting + :param proxy_url: a proxy to use """ def __init__(self, protocol='http', host='127.0.0.1', port=18081, path='/json_rpc', - user='', password='', timeout=30, verify_ssl_certs=True): + user='', password='', timeout=30, verify_ssl_certs=True, proxy_url=None): self.url = '{protocol}://{host}:{port}'.format( protocol=protocol, host=host, @@ -36,6 +37,7 @@ class JSONRPCDaemon(object): self.password = password self.timeout = timeout self.verify_ssl_certs = verify_ssl_certs + self.proxies = {protocol: proxy_url} def info(self): info = self.raw_jsonrpc_request('get_info') @@ -79,7 +81,7 @@ class JSONRPCDaemon(object): auth = requests.auth.HTTPDigestAuth(self.user, self.password) rsp = requests.post( self.url + path, headers=hdr, data=json.dumps(data), auth=auth, - timeout=self.timeout, verify=self.verify_ssl_certs) + timeout=self.timeout, verify=self.verify_ssl_certs, proxies=self.proxies) if rsp.status_code != 200: raise RPCError("Invalid HTTP status {code} for path {path}.".format( code=rsp.status_code, @@ -98,7 +100,7 @@ class JSONRPCDaemon(object): auth = requests.auth.HTTPDigestAuth(self.user, self.password) rsp = requests.post( self.url + '/json_rpc', headers=hdr, data=json.dumps(data), auth=auth, - timeout=self.timeout, verify=self.verify_ssl_certs) + timeout=self.timeout, verify=self.verify_ssl_certs, proxies=self.proxies) if rsp.status_code == 401: raise Unauthorized("401 Unauthorized. Invalid RPC user name or password.") diff --git a/utils/daemoninfo.py b/utils/daemoninfo.py index f4c3703..3689515 100755 --- a/utils/daemoninfo.py +++ b/utils/daemoninfo.py @@ -17,6 +17,7 @@ def get_daemon(): argsparser = argparse.ArgumentParser(description="Display daemon info") argsparser.add_argument('daemon_rpc_url', nargs='?', type=url_data, default='127.0.0.1:18081', help="Daemon RPC URL [host[:port]]") + argsparser.add_argument('-p', dest='proxy_url', nargs='?', type=str, default=None, help="Proxy URL") argsparser.add_argument('-t', dest='timeout', type=int, default=30, help="Request timeout") argsparser.add_argument('-v', dest='verbosity', action='count', default=0, help="Verbosity (repeat to increase; -v for INFO, -vv for DEBUG") @@ -27,7 +28,7 @@ def get_daemon(): elif args.verbosity > 1: level = logging.DEBUG logging.basicConfig(level=level, format="%(asctime)-15s %(message)s") - return Daemon(JSONRPCDaemon(timeout=args.timeout, **args.daemon_rpc_url)) + return Daemon(JSONRPCDaemon(timeout=args.timeout, proxy_url=args.proxy_url, **args.daemon_rpc_url)) d = get_daemon() info = d.info() diff --git a/utils/pushtx.py b/utils/pushtx.py index dfae54e..0a1419a 100755 --- a/utils/pushtx.py +++ b/utils/pushtx.py @@ -21,6 +21,8 @@ argsparser.add_argument('daemon_rpc_url', nargs='?', type=url_data, default='127 help="Daemon RPC URL [host[:port]]") argsparser.add_argument('-v', dest='verbosity', action='count', default=0, help="Verbosity (repeat to increase; -v for INFO, -vv for DEBUG") +argsparser.add_argument('-p', dest='proxy_url', nargs='?', type=str, default=None, + help="Proxy URL") argsparser.add_argument('-t', dest='timeout', type=int, default=30, help="Request timeout") argsparser.add_argument('-i', dest='tx_filenames', nargs='+', default=None, help="Files with transaction data. Will read from stdin if not given.") @@ -37,7 +39,7 @@ if args.tx_filenames: blobs = [(f, open(f, 'r').read()) for f in args.tx_filenames] else: blobs = [('transaction', sys.stdin.read())] -d = Daemon(JSONRPCDaemon(timeout=args.timeout, **args.daemon_rpc_url)) +d = Daemon(JSONRPCDaemon(timeout=args.timeout, proxy_url=args.proxy_url, **args.daemon_rpc_url)) for name, blob in blobs: logging.debug("Sending {}".format(name)) tx = Transaction(blob=blob) diff --git a/utils/transfer.py b/utils/transfer.py index 827b93c..2d82ceb 100755 --- a/utils/transfer.py +++ b/utils/transfer.py @@ -27,7 +27,7 @@ argsparser = argparse.ArgumentParser(description="Transfer Monero") argsparser.add_argument('-v', dest='verbosity', action='count', default=0, help="Verbosity (repeat to increase; -v for INFO, -vv for DEBUG") argsparser.add_argument('wallet_rpc_url', nargs='?', type=url_data, default='127.0.0.1:18082', - help="Daemon URL [user[:password]@]host[:port]") + help="Wallet RPC URL [user[:password]@]host[:port]") argsparser.add_argument('-t', dest='timeout', type=int, default=30, help="Request timeout") argsparser.add_argument('-a', dest='account', default=0, type=int, help="Source account index") argsparser.add_argument('-p', dest='prio',