prevent dns leaks when using proxy. fixes issue #147
This commit is contained in:
parent
89a9ce2ab4
commit
27cc09e8e2
|
@ -17,9 +17,11 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import random, socket, ast, re, ssl, errno, os
|
||||
import random, ast, re, errno, os
|
||||
import threading, traceback, sys, time, json, Queue
|
||||
import socks
|
||||
import socket
|
||||
import ssl
|
||||
|
||||
from version import ELECTRUM_VERSION, PROTOCOL_VERSION
|
||||
from util import print_error, print_msg
|
||||
|
@ -60,6 +62,7 @@ class Interface(threading.Thread):
|
|||
s = config.get('server')
|
||||
host, port, protocol = s.split(':')
|
||||
port = int(port)
|
||||
|
||||
if protocol not in 'ghst':
|
||||
raise BaseException('Unknown protocol: %s'%protocol)
|
||||
|
||||
|
@ -68,6 +71,8 @@ class Interface(threading.Thread):
|
|||
self.protocol = protocol
|
||||
self.use_ssl = ( protocol in 'sg' )
|
||||
self.proxy = self.parse_proxy_options(config.get('proxy'))
|
||||
if self.proxy:
|
||||
self.proxy_mode = proxy_modes.index(self.proxy["mode"]) + 1
|
||||
self.server = host + ':%d:%s'%(port, protocol)
|
||||
|
||||
|
||||
|
@ -174,7 +179,7 @@ class Interface(threading.Thread):
|
|||
print_error( "send_http", messages )
|
||||
|
||||
if self.proxy:
|
||||
socks.setdefaultproxy(proxy_modes.index(self.proxy["mode"]) + 1, self.proxy["host"], int(self.proxy["port"]) )
|
||||
socks.setdefaultproxy(self.proxy_mode, self.proxy["host"], int(self.proxy["port"]) )
|
||||
socks.wrapmodule(urllib2)
|
||||
|
||||
cj = cookielib.CookieJar()
|
||||
|
@ -237,31 +242,37 @@ class Interface(threading.Thread):
|
|||
|
||||
def start_tcp(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:
|
||||
cert_path = os.path.join( self.config.get('path'), 'certs', self.host)
|
||||
if not os.path.exists(cert_path):
|
||||
dir_path = os.path.join( self.config.get('path'), 'certs')
|
||||
if not os.path.exists(dir_path):
|
||||
os.mkdir(dir_path)
|
||||
# get server certificate.
|
||||
# Do not use ssl.get_server_certificate because it does not work with proxy
|
||||
s = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
||||
try:
|
||||
cert = ssl.get_server_certificate((self.host, self.port))
|
||||
s.connect((self.host, self.port))
|
||||
except:
|
||||
print_error("failed to connect", self.host, self.port)
|
||||
return
|
||||
|
||||
s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv3, cert_reqs=ssl.CERT_NONE, ca_certs=None)
|
||||
dercert = s.getpeercert(True)
|
||||
s.close()
|
||||
cert = ssl.DER_cert_to_PEM_cert(dercert)
|
||||
|
||||
with open(cert_path,"w") as f:
|
||||
f.write(cert)
|
||||
|
||||
self.connection_msg = "%s:%d"%(self.host, self.port)
|
||||
|
||||
|
||||
if self.proxy is None:
|
||||
s = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
||||
else:
|
||||
self.connection_msg += " using proxy %s:%s:%s"%(self.proxy.get('mode'), self.proxy.get('host'), self.proxy.get('port'))
|
||||
s = socks.socksocket()
|
||||
s.setproxy(proxy_modes.index(self.proxy["mode"]) + 1, self.proxy["host"], int(self.proxy["port"]) )
|
||||
|
||||
s = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
||||
s.settimeout(2)
|
||||
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
|
||||
|
||||
|
|
|
@ -56,6 +56,10 @@ class Network(threading.Thread):
|
|||
self.proxy = self.config.get('proxy')
|
||||
self.heights = {}
|
||||
|
||||
dir_path = os.path.join( self.config.path, 'certs')
|
||||
if not os.path.exists(dir_path):
|
||||
os.mkdir(dir_path)
|
||||
|
||||
|
||||
def register_callback(self, event, callback):
|
||||
with self.lock:
|
||||
|
|
Loading…
Reference in New Issue