1
0

aiorpcx: socks support

This commit is contained in:
Janus
2018-08-27 20:39:36 +02:00
committed by SomberNight
parent c53caecd1e
commit f733cb8947
5 changed files with 77 additions and 35 deletions

View File

@@ -34,7 +34,7 @@ import asyncio
import requests
from .util import PrintError
from .util import PrintError, aiosafe, bfh
ca_path = requests.certs.where()
@@ -42,16 +42,38 @@ from . import util
from . import x509
from . import pem
from .version import ELECTRUM_VERSION, PROTOCOL_VERSION
from .util import NotificationSession
class Interface(PrintError):
def __init__(self, server, config_path, connecting):
def __init__(self, server, config_path, connecting, proxy):
self.exception = None
self.connecting = connecting
self.server = server
self.host, self.port, self.protocol = self.server.split(':')
self.port = int(self.port)
self.config_path = config_path
self.cert_path = os.path.join(self.config_path, 'certs', self.host)
self.fut = asyncio.get_event_loop().create_task(self.run())
if proxy:
proxy['user'] = proxy.get('user', '')
if proxy['user'] == '':
proxy['user'] = 'sampleuser' # aiorpcx doesn't allow empty user
proxy['password'] = proxy.get('password', '')
if proxy['password'] == '':
proxy['password'] = 'samplepassword'
try:
auth = aiorpcx.socks.SOCKSUserAuth(proxy['user'], proxy['password'])
except KeyError:
auth = None
if proxy['mode'] == "socks4":
self.proxy = aiorpcx.socks.SOCKSProxy((proxy['host'], int(proxy['port'])), aiorpcx.socks.SOCKS4a, auth)
elif proxy['mode'] == "socks5":
self.proxy = aiorpcx.socks.SOCKSProxy((proxy['host'], int(proxy['port'])), aiorpcx.socks.SOCKS5, auth)
else:
raise NotImplementedError
else:
self.proxy = None
def diagnostic_name(self):
return self.host
@@ -67,8 +89,8 @@ class Interface(PrintError):
@util.aiosafe
async def run(self):
if self.protocol != 's':
await self.open_session(None, execute_after_connect=lambda: self.connecting.remove(self.server))
return
await self.open_session(None, execute_after_connect=self.mark_ready)
assert False
ca_sslc = ssl.create_default_context(ssl.Purpose.SERVER_AUTH)
exists = os.path.exists(self.cert_path)
@@ -84,8 +106,8 @@ class Interface(PrintError):
x = x509.X509(b)
try:
x.check_date()
except x509.CertificateError:
self.print_error("certificate has expired:", self.cert_path)
except x509.CertificateError as e:
self.print_error("certificate problem", e)
os.unlink(self.cert_path)
exists = False
if not exists:
@@ -102,7 +124,11 @@ class Interface(PrintError):
else:
sslc = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=self.cert_path)
sslc.check_hostname = 0
await self.open_session(sslc, execute_after_connect=lambda: self.connecting.remove(self.server))
await self.open_session(sslc, execute_after_connect=self.mark_ready)
assert False
def mark_ready(self):
self.connecting.remove(self.server)
async def save_certificate(self):
if not os.path.exists(self.cert_path):
@@ -129,13 +155,13 @@ class Interface(PrintError):
async def get_certificate(self):
sslc = ssl.SSLContext()
try:
async with aiorpcx.ClientSession(self.host, self.port, ssl=sslc) as session:
async with aiorpcx.ClientSession(self.host, self.port, ssl=sslc, proxy=self.proxy) as session:
return session.transport._ssl_protocol._sslpipe._sslobj.getpeercert(True)
except ValueError:
return None
async def open_session(self, sslc, do_sleep=True, execute_after_connect=lambda: None):
async with aiorpcx.ClientSession(self.host, self.port, ssl=sslc) as session:
async with NotificationSession(None, None, self.host, self.port, ssl=sslc, proxy=self.proxy) as session:
ver = await session.send_request('server.version', [ELECTRUM_VERSION, PROTOCOL_VERSION])
print(ver)
connect_hook_executed = False
@@ -146,9 +172,6 @@ class Interface(PrintError):
await asyncio.wait_for(session.send_request('server.ping'), 5)
await asyncio.sleep(300)
def has_timed_out(self):
return self.fut.done()
def queue_request(self, method, params, msg_id):
pass