simplify interface.get_socket, and fix a bug with new certificates
This commit is contained in:
parent
99b60980cd
commit
889ac782c1
106
lib/interface.py
106
lib/interface.py
|
@ -55,15 +55,12 @@ class TcpInterface(threading.Thread):
|
||||||
self.daemon = True
|
self.daemon = True
|
||||||
self.config = config if config is not None else SimpleConfig()
|
self.config = config if config is not None else SimpleConfig()
|
||||||
self.lock = threading.Lock()
|
self.lock = threading.Lock()
|
||||||
|
|
||||||
self.is_connected = False
|
self.is_connected = False
|
||||||
self.debug = False # dump network messages. can be changed at runtime using the console
|
self.debug = False # dump network messages. can be changed at runtime using the console
|
||||||
self.message_id = 0
|
self.message_id = 0
|
||||||
self.unanswered_requests = {}
|
self.unanswered_requests = {}
|
||||||
|
|
||||||
# are we waiting for a pong?
|
# are we waiting for a pong?
|
||||||
self.is_ping = False
|
self.is_ping = False
|
||||||
|
|
||||||
# parse server
|
# parse server
|
||||||
self.server = server
|
self.server = server
|
||||||
self.host, self.port, self.protocol = self.server.split(':')
|
self.host, self.port, self.protocol = self.server.split(':')
|
||||||
|
@ -72,6 +69,12 @@ class TcpInterface(threading.Thread):
|
||||||
self.proxy = self.parse_proxy_options(self.config.get('proxy'))
|
self.proxy = self.parse_proxy_options(self.config.get('proxy'))
|
||||||
if self.proxy:
|
if self.proxy:
|
||||||
self.proxy_mode = proxy_modes.index(self.proxy["mode"]) + 1
|
self.proxy_mode = proxy_modes.index(self.proxy["mode"]) + 1
|
||||||
|
socks.setdefaultproxy(self.proxy_mode, self.proxy["host"], int(self.proxy["port"]))
|
||||||
|
socket.socket = socks.socksocket
|
||||||
|
# prevent dns leaks, see http://stackoverflow.com/questions/13184205/dns-over-proxy
|
||||||
|
def getaddrinfo(*args):
|
||||||
|
return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (args[0], args[1]))]
|
||||||
|
socket.getaddrinfo = getaddrinfo
|
||||||
|
|
||||||
|
|
||||||
def process_response(self, response):
|
def process_response(self, response):
|
||||||
|
@ -116,54 +119,48 @@ class TcpInterface(threading.Thread):
|
||||||
queue.put((self, {'method':method, 'params':params, 'result':result, 'id':_id}))
|
queue.put((self, {'method':method, 'params':params, 'result':result, 'id':_id}))
|
||||||
|
|
||||||
|
|
||||||
|
def get_simple_socket(self):
|
||||||
|
try:
|
||||||
|
l = socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM)
|
||||||
|
except socket.gaierror:
|
||||||
|
print_error("error: cannot resolve", self.host)
|
||||||
|
return
|
||||||
|
for res in l:
|
||||||
|
try:
|
||||||
|
s = socket.socket(res[0], socket.SOCK_STREAM)
|
||||||
|
s.connect(res[4])
|
||||||
|
return s
|
||||||
|
except:
|
||||||
|
continue
|
||||||
|
else:
|
||||||
|
print_error("failed to connect", self.host, self.port)
|
||||||
|
|
||||||
|
|
||||||
def get_socket(self):
|
def get_socket(self):
|
||||||
|
|
||||||
if self.proxy is not None:
|
|
||||||
socks.setdefaultproxy(self.proxy_mode, self.proxy["host"], int(self.proxy["port"]))
|
|
||||||
socket.socket = socks.socksocket
|
|
||||||
# prevent dns leaks, see http://stackoverflow.com/questions/13184205/dns-over-proxy
|
|
||||||
def getaddrinfo(*args):
|
|
||||||
return [(socket.AF_INET, socket.SOCK_STREAM, 6, '', (args[0], args[1]))]
|
|
||||||
socket.getaddrinfo = getaddrinfo
|
|
||||||
|
|
||||||
if self.use_ssl:
|
if self.use_ssl:
|
||||||
cert_path = os.path.join( self.config.path, 'certs', self.host)
|
cert_path = os.path.join( self.config.path, 'certs', self.host)
|
||||||
if not os.path.exists(cert_path):
|
if not os.path.exists(cert_path):
|
||||||
is_new = True
|
is_new = True
|
||||||
# get server certificate.
|
s = self.get_simple_socket()
|
||||||
# Do not use ssl.get_server_certificate because it does not work with proxy
|
if s is None:
|
||||||
try:
|
|
||||||
l = socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM)
|
|
||||||
except socket.gaierror:
|
|
||||||
print_error("error: cannot resolve", self.host)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
for res in l:
|
# try with CA first
|
||||||
try:
|
try:
|
||||||
s = socket.socket( res[0], socket.SOCK_STREAM )
|
ca_certs = os.path.join(self.config.path, 'ca', 'ca-bundle.crt')
|
||||||
s.connect(res[4])
|
s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv3, cert_reqs=ssl.CERT_REQUIRED, ca_certs=ca_certs, do_handshake_on_connect=True)
|
||||||
except:
|
print_error("SSL with ca:", self.host)
|
||||||
s = None
|
return s
|
||||||
continue
|
except ssl.SSLError, e:
|
||||||
|
pass
|
||||||
|
|
||||||
# first try with ca
|
# get server certificate.
|
||||||
try:
|
# Do not use ssl.get_server_certificate because it does not work with proxy
|
||||||
ca_certs = os.path.join(self.config.path, 'ca', 'ca-bundle.crt')
|
s = self.get_simple_socket()
|
||||||
s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv3, cert_reqs=ssl.CERT_REQUIRED, ca_certs=ca_certs, do_handshake_on_connect=True)
|
try:
|
||||||
print_error("SSL with ca:", self.host)
|
s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv3, cert_reqs=ssl.CERT_NONE, ca_certs=None)
|
||||||
return s
|
except ssl.SSLError, e:
|
||||||
except ssl.SSLError, e:
|
print_error("SSL error retrieving SSL certificate:", self.host, e)
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv3, cert_reqs=ssl.CERT_NONE, ca_certs=None)
|
|
||||||
except ssl.SSLError, e:
|
|
||||||
print_error("SSL error retrieving SSL certificate:", self.host, e)
|
|
||||||
s = None
|
|
||||||
|
|
||||||
break
|
|
||||||
|
|
||||||
if s is None:
|
|
||||||
return
|
return
|
||||||
|
|
||||||
dercert = s.getpeercert(True)
|
dercert = s.getpeercert(True)
|
||||||
|
@ -174,31 +171,16 @@ class TcpInterface(threading.Thread):
|
||||||
temporary_path = cert_path + '.temp'
|
temporary_path = cert_path + '.temp'
|
||||||
with open(temporary_path,"w") as f:
|
with open(temporary_path,"w") as f:
|
||||||
f.write(cert)
|
f.write(cert)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
is_new = False
|
is_new = False
|
||||||
|
|
||||||
try:
|
s = self.get_simple_socket()
|
||||||
addrinfo = socket.getaddrinfo(self.host, self.port, socket.AF_UNSPEC, socket.SOCK_STREAM)
|
|
||||||
except socket.gaierror:
|
|
||||||
print_error("error: cannot resolve", self.host)
|
|
||||||
return
|
|
||||||
|
|
||||||
for res in addrinfo:
|
|
||||||
try:
|
|
||||||
s = socket.socket( res[0], socket.SOCK_STREAM )
|
|
||||||
s.settimeout(2)
|
|
||||||
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
|
||||||
s.connect(res[4])
|
|
||||||
except:
|
|
||||||
s = None
|
|
||||||
continue
|
|
||||||
break
|
|
||||||
|
|
||||||
if s is None:
|
if s is None:
|
||||||
print_error("failed to connect", self.host, self.port)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
s.settimeout(2)
|
||||||
|
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
||||||
|
|
||||||
if self.use_ssl:
|
if self.use_ssl:
|
||||||
try:
|
try:
|
||||||
s = ssl.wrap_socket(s,
|
s = ssl.wrap_socket(s,
|
||||||
|
|
Loading…
Reference in New Issue