URI: 
       tprevent dns leaks when using proxy. fixes issue #147 - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit 27cc09e8e229e4e55ebf5ae010803bd4730da841
   DIR parent 89a9ce2ab4520c39148a83d66f1fc553612f64d3
  HTML Author: ThomasV <thomasv@gitorious>
       Date:   Tue,  1 Oct 2013 11:24:55 +0200
       
       prevent dns leaks when using proxy. fixes issue #147
       
       Diffstat:
         M lib/interface.py                    |      41 ++++++++++++++++++++-----------
         M lib/network.py                      |       4 ++++
       
       2 files changed, 30 insertions(+), 15 deletions(-)
       ---
   DIR diff --git a/lib/interface.py b/lib/interface.py
       t@@ -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
       t@@ -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)
        
       t@@ -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)
        
        
       t@@ -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()
       t@@ -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)
        
   DIR diff --git a/lib/network.py b/lib/network.py
       t@@ -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: