SSL certificate validation

This commit is contained in:
thomasv 2013-09-30 14:01:49 +02:00
parent 9e70c7fae4
commit a6002cf71c
2 changed files with 57 additions and 8 deletions

View File

@ -17,8 +17,9 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import random, socket, ast, re, ssl, errno import random, socket, ast, re, ssl, errno, os
import threading, traceback, sys, time, json, Queue import threading, traceback, sys, time, json, Queue
import socks
from version import ELECTRUM_VERSION, PROTOCOL_VERSION from version import ELECTRUM_VERSION, PROTOCOL_VERSION
from util import print_error, print_msg from util import print_error, print_msg
@ -147,7 +148,6 @@ class Interface(threading.Thread):
print_error( "send_http", messages ) print_error( "send_http", messages )
if self.proxy: if self.proxy:
import socks
socks.setdefaultproxy(proxy_modes.index(self.proxy["mode"]) + 1, self.proxy["host"], int(self.proxy["port"]) ) socks.setdefaultproxy(proxy_modes.index(self.proxy["mode"]) + 1, self.proxy["host"], int(self.proxy["port"]) )
socks.wrapmodule(urllib2) socks.wrapmodule(urllib2)
@ -210,36 +210,74 @@ class Interface(threading.Thread):
def init_tcp(self, host, port, proxy=None, use_ssl=True): def init_tcp(self, host, port, proxy=None, use_ssl=True):
if self.use_ssl:
cert_path = os.path.join( self.config.get('path'), 'certs', 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)
try:
cert = ssl.get_server_certificate((host, port))
except:
print_error("failed to connect", host, port)
return
with open(cert_path,"w") as f:
f.write(cert)
self.init_server(host, port, proxy, use_ssl) self.init_server(host, port, proxy, use_ssl)
global proxy_modes global proxy_modes
self.connection_msg = "%s:%d"%(self.host,self.port) self.connection_msg = "%s:%d"%(self.host,self.port)
if self.proxy is None: if self.proxy is None:
s = socket.socket( socket.AF_INET, socket.SOCK_STREAM ) s = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
else: else:
self.connection_msg += " using proxy %s:%s:%s"%(self.proxy.get('mode'), self.proxy.get('host'), self.proxy.get('port')) self.connection_msg += " using proxy %s:%s:%s"%(self.proxy.get('mode'), self.proxy.get('host'), self.proxy.get('port'))
import socks
s = socks.socksocket() s = socks.socksocket()
s.setproxy(proxy_modes.index(self.proxy["mode"]) + 1, self.proxy["host"], int(self.proxy["port"]) ) s.setproxy(proxy_modes.index(self.proxy["mode"]) + 1, self.proxy["host"], int(self.proxy["port"]) )
if self.use_ssl: if self.use_ssl:
s = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_SSLv23, do_handshake_on_connect=True) try:
s = ssl.wrap_socket(s,
ssl_version=ssl.PROTOCOL_SSLv3,
cert_reqs=ssl.CERT_REQUIRED,
ca_certs=cert_path,
do_handshake_on_connect=True)
except:
print_error("wrap_socket failed", host)
return
s.settimeout(2) s.settimeout(2)
s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
try: try:
s.connect(( self.host.encode('ascii'), int(self.port))) s.connect(( self.host.encode('ascii'), int(self.port)))
except ssl.SSLError, e:
print_error("SSL error:", host, e)
return
except: except:
#traceback.print_exc(file=sys.stdout) #traceback.print_exc(file=sys.stdout)
print_error("failed to connect", host, port) print_error("failed to connect", host, port)
self.is_connected = False return
self.s = None
# hostname verification (disabled)
if self.use_ssl and False:
from backports.ssl_match_hostname import match_hostname, CertificateError
try:
match_hostname(s.getpeercert(), host)
print_error("hostname matches", host)
except CertificateError, ce:
print_error("hostname does not match", host, s.getpeercert())
return return
s.settimeout(60) s.settimeout(60)
self.s = s self.s = s
self.is_connected = True self.is_connected = True
print_error("connected to", host, port)
def run_tcp(self): def run_tcp(self):
try: try:
@ -479,3 +517,14 @@ class Interface(threading.Thread):
#print "change status", self.server, self.is_connected #print "change status", self.server, self.is_connected
self.queue.put(self) self.queue.put(self)
if __name__ == "__main__":
q = Queue.Queue()
i = Interface({'server':'btc.it-zone.org:50002:s', 'path':'/extra/key/wallet', 'verbose':True})
i.start(q)
time.sleep(1)
exit()

View File

@ -95,7 +95,7 @@ class Network(threading.Thread):
def start_interface(self, server): def start_interface(self, server):
if server in self.interfaces.keys(): if server in self.interfaces.keys():
return return
i = interface.Interface({'server':server}) i = interface.Interface({'server':server, 'path':self.config.path})
self.interfaces[server] = i self.interfaces[server] = i
i.start(self.queue) i.start(self.queue)