<s> import random , ast , re , errno , os <EOL> import threading , traceback , sys , time , json , Queue <EOL> import socks <EOL> import socket <EOL> import ssl <EOL> from version import ELECTRUM_VERSION , PROTOCOL_VERSION <EOL> from util import print_error , print_msg <EOL> from simple_config import SimpleConfig <EOL> DEFAULT_TIMEOUT = <NUM_LIT:5> <EOL> proxy_modes = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:http>' ] <EOL> def check_cert ( host , cert ) : <EOL> from OpenSSL import crypto as c <EOL> _cert = c . load_certificate ( c . FILETYPE_PEM , cert ) <EOL> m = "<STR_LIT>" % host <EOL> m += "<STR_LIT>" % _cert . has_expired ( ) <EOL> m += "<STR_LIT>" % _cert . get_pubkey ( ) . bits ( ) <EOL> m += "<STR_LIT>" % _cert . get_serial_number ( ) <EOL> m += "<STR_LIT>" % _cert . get_version ( ) <EOL> print_msg ( m ) <EOL> def cert_has_expired ( cert_path ) : <EOL> try : <EOL> import OpenSSL <EOL> except Exception : <EOL> print_error ( "<STR_LIT>" ) <EOL> return False <EOL> from OpenSSL import crypto as c <EOL> with open ( cert_path ) as f : <EOL> cert = f . read ( ) <EOL> _cert = c . load_certificate ( c . FILETYPE_PEM , cert ) <EOL> return _cert . has_expired ( ) <EOL> def check_certificates ( ) : <EOL> config = SimpleConfig ( ) <EOL> mydir = os . path . join ( config . path , "<STR_LIT>" ) <EOL> certs = os . listdir ( mydir ) <EOL> for c in certs : <EOL> print c <EOL> p = os . path . join ( mydir , c ) <EOL> with open ( p ) as f : <EOL> cert = f . read ( ) <EOL> check_cert ( c , cert ) <EOL> def cert_verify_hostname ( s ) : <EOL> from backports . ssl_match_hostname import match_hostname , CertificateError <EOL> try : <EOL> match_hostname ( s . getpeercert ( True ) , host ) <EOL> print_error ( "<STR_LIT>" , host ) <EOL> except CertificateError , ce : <EOL> print_error ( "<STR_LIT>" , host ) <EOL> class Interface ( threading . Thread ) : <EOL> def __init__ ( self , server , config = None ) : <EOL> threading . Thread . __init__ ( self ) <EOL> self . daemon = True <EOL> self . config = config if config is not None else SimpleConfig ( ) <EOL> self . connect_event = threading . Event ( ) <EOL> self . subscriptions = { } <EOL> self . lock = threading . Lock ( ) <EOL> self . rtime = <NUM_LIT:0> <EOL> self . bytes_received = <NUM_LIT:0> <EOL> self . is_connected = False <EOL> self . poll_interval = <NUM_LIT:1> <EOL> self . debug = False <EOL> self . message_id = <NUM_LIT:0> <EOL> self . unanswered_requests = { } <EOL> self . pending_transactions_for_notifications = [ ] <EOL> self . server = server <EOL> try : <EOL> host , port , protocol = self . server . split ( '<STR_LIT::>' ) <EOL> port = int ( port ) <EOL> except Exception : <EOL> self . server = None <EOL> return <EOL> if protocol not in '<STR_LIT>' : <EOL> raise Exception ( '<STR_LIT>' % protocol ) <EOL> self . host = host <EOL> self . port = port <EOL> self . protocol = protocol <EOL> self . use_ssl = ( protocol in '<STR_LIT>' ) <EOL> self . proxy = self . parse_proxy_options ( self . config . get ( '<STR_LIT>' ) ) <EOL> if self . proxy : <EOL> self . proxy_mode = proxy_modes . index ( self . proxy [ "<STR_LIT>" ] ) + <NUM_LIT:1> <EOL> def queue_json_response ( self , c ) : <EOL> if self . debug : <EOL> print_error ( "<STR_LIT>" , c ) <EOL> msg_id = c . get ( '<STR_LIT:id>' ) <EOL> error = c . get ( '<STR_LIT:error>' ) <EOL> if error : <EOL> print_error ( "<STR_LIT>" , c ) <EOL> if msg_id is not None : <EOL> with self . lock : <EOL> method , params , callback = self . unanswered_requests . pop ( msg_id ) <EOL> callback ( self , { '<STR_LIT>' : method , '<STR_LIT>' : params , '<STR_LIT:error>' : error , '<STR_LIT:id>' : msg_id } ) <EOL> return <EOL> if msg_id is not None : <EOL> with self . lock : <EOL> method , params , callback = self . unanswered_requests . pop ( msg_id ) <EOL> result = c . get ( '<STR_LIT:result>' ) <EOL> else : <EOL> method = c . get ( '<STR_LIT>' ) <EOL> params = c . get ( '<STR_LIT>' ) <EOL> if method == '<STR_LIT>' : <EOL> result = params [ <NUM_LIT:0> ] <EOL> params = [ ] <EOL> elif method == '<STR_LIT>' : <EOL> result = params [ <NUM_LIT:0> ] <EOL> params = [ ] <EOL> elif method == '<STR_LIT>' : <EOL> addr = params [ <NUM_LIT:0> ] <EOL> result = params [ <NUM_LIT:1> ] <EOL> params = [ addr ] <EOL> with self . lock : <EOL> for k , v in self . subscriptions . items ( ) : <EOL> if ( method , params ) in v : <EOL> callback = k <EOL> break <EOL> else : <EOL> print_error ( "<STR_LIT>" , method , params ) <EOL> print_error ( self . subscriptions ) <EOL> return <EOL> callback ( self , { '<STR_LIT>' : method , '<STR_LIT>' : params , '<STR_LIT:result>' : result , '<STR_LIT:id>' : msg_id } ) <EOL> def on_version ( self , i , result ) : <EOL> self . server_version = result <EOL> def start_http ( self ) : <EOL> self . session_id = None <EOL> self . is_connected = True <EOL> self . connection_msg = ( '<STR_LIT>' if self . use_ssl else '<STR_LIT:http>' ) + '<STR_LIT>' % ( self . host , self . port ) <EOL> try : <EOL> self . poll ( ) <EOL> except Exception : <EOL> print_error ( "<STR_LIT>" ) <EOL> self . is_connected = False <EOL> return <EOL> if self . session_id : <EOL> print_error ( '<STR_LIT>' , self . session_id ) <EOL> self . is_connected = True <EOL> else : <EOL> self . is_connected = False <EOL> def run_http ( self ) : <EOL> self . is_connected = True <EOL> while self . is_connected : <EOL> try : <EOL> if self . session_id : <EOL> self . poll ( ) <EOL> time . sleep ( self . poll_interval ) <EOL> except socket . gaierror : <EOL> break <EOL> except socket . error : <EOL> break <EOL> except Exception : <EOL> traceback . print_exc ( file = sys . stdout ) <EOL> break <EOL> self . is_connected = False <EOL> def poll ( self ) : <EOL> self . send ( [ ] , None ) <EOL> def send_http ( self , messages , callback ) : <EOL> import urllib2 , json , time , cookielib <EOL> print_error ( "<STR_LIT>" , messages ) <EOL> if self . proxy : <EOL> socks . setdefaultproxy ( self . proxy_mode , self . proxy [ "<STR_LIT:host>" ] , int ( self . proxy [ "<STR_LIT:port>" ] ) ) <EOL> socks . wrapmodule ( urllib2 ) <EOL> cj = cookielib . CookieJar ( ) <EOL> opener = urllib2 . build_opener ( urllib2 . HTTPCookieProcessor ( cj ) ) <EOL> urllib2 . install_opener ( opener ) <EOL> t1 = time . time ( ) <EOL> data = [ ] <EOL> ids = [ ] <EOL> for m in messages : <EOL> method , params = m <EOL> if type ( params ) != type ( [ ] ) : params = [ params ] <EOL> data . append ( { '<STR_LIT>' : method , '<STR_LIT:id>' : self . message_id , '<STR_LIT>' : params } ) <EOL> self . unanswered_requests [ self . message_id ] = method , params , callback <EOL> ids . append ( self . message_id ) <EOL> self . message_id += <NUM_LIT:1> <EOL> if data : <EOL> data_json = json . dumps ( data ) <EOL> else : <EOL> data_json = None <EOL> headers = { '<STR_LIT>' : '<STR_LIT:application/json>' } <EOL> if self . session_id : <EOL> headers [ '<STR_LIT>' ] = '<STR_LIT>' % self . session_id <EOL> try : <EOL> req = urllib2 . Request ( self . connection_msg , data_json , headers ) <EOL> response_stream = urllib2 . urlopen ( req , timeout = DEFAULT_TIMEOUT ) <EOL> except Exception : <EOL> return <EOL> for index , cookie in enumerate ( cj ) : <EOL> if cookie . name == '<STR_LIT>' : <EOL> self . session_id = cookie . value <EOL> response = response_stream . read ( ) <EOL> self . bytes_received += len ( response ) <EOL> if response : <EOL> response = json . loads ( response ) <EOL> if type ( response ) is not type ( [ ] ) : <EOL> self . queue_json_response ( response ) <EOL> else : <EOL> for item in response : <EOL> self . queue_json_response ( item ) <EOL> if response : <EOL> self . poll_interval = <NUM_LIT:1> <EOL> else : <EOL> if self . poll_interval < <NUM_LIT:15> : <EOL> self . poll_interval += <NUM_LIT:1> <EOL> self . rtime = time . time ( ) - t1 <EOL> self . is_connected = True <EOL> return ids <EOL> def start_tcp ( self ) : <EOL> self . connection_msg = self . host + '<STR_LIT>' % self . port <EOL> if self . proxy is not None : <EOL> socks . setdefaultproxy ( self . proxy_mode , self . proxy [ "<STR_LIT:host>" ] , int ( self . proxy [ "<STR_LIT:port>" ] ) ) <EOL> socket . socket = socks . socksocket <EOL> def getaddrinfo ( * args ) : <EOL> return [ ( socket . AF_INET , socket . SOCK_STREAM , <NUM_LIT:6> , '<STR_LIT>' , ( args [ <NUM_LIT:0> ] , args [ <NUM_LIT:1> ] ) ) ] <EOL> socket . getaddrinfo = getaddrinfo <EOL> if self . use_ssl : <EOL> cert_path = os . path . join ( self . config . path , '<STR_LIT>' , self . host ) <EOL> if not os . path . exists ( cert_path ) : <EOL> is_new = True <EOL> try : <EOL> l = socket . getaddrinfo ( self . host , self . port , socket . AF_UNSPEC , socket . SOCK_STREAM ) <EOL> except socket . gaierror : <EOL> print_error ( "<STR_LIT>" , self . host ) <EOL> return <EOL> for res in l : <EOL> try : <EOL> s = socket . socket ( res [ <NUM_LIT:0> ] , socket . SOCK_STREAM ) <EOL> s . connect ( res [ <NUM_LIT:4> ] ) <EOL> except : <EOL> s = None <EOL> continue <EOL> try : <EOL> s = ssl . wrap_socket ( s , ssl_version = ssl . PROTOCOL_SSLv3 , cert_reqs = ssl . CERT_NONE , ca_certs = None ) <EOL> except ssl . SSLError , e : <EOL> print_error ( "<STR_LIT>" , self . host , e ) <EOL> s = None <EOL> break <EOL> if s is None : <EOL> return <EOL> dercert = s . getpeercert ( True ) <EOL> s . close ( ) <EOL> cert = ssl . DER_cert_to_PEM_cert ( dercert ) <EOL> cert = re . sub ( "<STR_LIT>" , "<STR_LIT>" , cert ) <EOL> temporary_path = cert_path + '<STR_LIT>' <EOL> with open ( temporary_path , "<STR_LIT:w>" ) as f : <EOL> f . write ( cert ) <EOL> else : <EOL> is_new = False <EOL> try : <EOL> addrinfo = socket . getaddrinfo ( self . host , self . port , socket . AF_UNSPEC , socket . SOCK_STREAM ) <EOL> except socket . gaierror : <EOL> print_error ( "<STR_LIT>" , self . host ) <EOL> return <EOL> for res in addrinfo : <EOL> try : <EOL> s = socket . socket ( res [ <NUM_LIT:0> ] , socket . SOCK_STREAM ) <EOL> s . settimeout ( <NUM_LIT:2> ) <EOL> s . setsockopt ( socket . SOL_SOCKET , socket . SO_KEEPALIVE , <NUM_LIT:1> ) <EOL> s . connect ( res [ <NUM_LIT:4> ] ) <EOL> except : <EOL> s = None <EOL> continue <EOL> break <EOL> if s is None : <EOL> print_error ( "<STR_LIT>" , self . host , self . port ) <EOL> return <EOL> if self . use_ssl : <EOL> try : <EOL> s = ssl . wrap_socket ( s , <EOL> ssl_version = ssl . PROTOCOL_SSLv3 , <EOL> cert_reqs = ssl . CERT_REQUIRED , <EOL> ca_certs = ( temporary_path if is_new else cert_path ) , <EOL> do_handshake_on_connect = True ) <EOL> except ssl . SSLError , e : <EOL> print_error ( "<STR_LIT>" , self . host , e ) <EOL> if e . errno != <NUM_LIT:1> : <EOL> return <EOL> if is_new : <EOL> rej = cert_path + '<STR_LIT>' <EOL> if os . path . exists ( rej ) : <EOL> os . unlink ( rej ) <EOL> os . rename ( temporary_path , rej ) <EOL> else : <EOL> if cert_has_expired ( cert_path ) : <EOL> print_error ( "<STR_LIT>" , cert_path ) <EOL> os . unlink ( cert_path ) <EOL> else : <EOL> print_msg ( "<STR_LIT>" , self . host ) <EOL> return <EOL> except Exception : <EOL> print_error ( "<STR_LIT>" , self . host ) <EOL> traceback . print_exc ( file = sys . stdout ) <EOL> return <EOL> if is_new : <EOL> print_error ( "<STR_LIT>" , self . host ) <EOL> os . rename ( temporary_path , cert_path ) <EOL> s . settimeout ( <NUM_LIT> ) <EOL> self . s = s <EOL> self . is_connected = True <EOL> print_error ( "<STR_LIT>" , self . host , self . port ) <EOL> def run_tcp ( self ) : <EOL> try : <EOL> out = '<STR_LIT>' <EOL> while self . is_connected : <EOL> try : <EOL> timeout = False <EOL> msg = self . s . recv ( <NUM_LIT> ) <EOL> except socket . timeout : <EOL> timeout = True <EOL> except ssl . SSLError : <EOL> timeout = True <EOL> except socket . error , err : <EOL> if err . errno == <NUM_LIT> : <EOL> timeout = True <EOL> elif err . errno in [ <NUM_LIT:11> , <NUM_LIT> ] : <EOL> print_error ( "<STR_LIT>" , err . errno ) <EOL> time . sleep ( <NUM_LIT:0.1> ) <EOL> continue <EOL> else : <EOL> traceback . print_exc ( file = sys . stdout ) <EOL> raise <EOL> if timeout : <EOL> self . send ( [ ( '<STR_LIT>' , [ ELECTRUM_VERSION , PROTOCOL_VERSION ] ) ] , self . on_version ) <EOL> continue <EOL> out += msg <EOL> self . bytes_received += len ( msg ) <EOL> if msg == '<STR_LIT>' : <EOL> self . is_connected = False <EOL> while True : <EOL> s = out . find ( '<STR_LIT:\n>' ) <EOL> if s == - <NUM_LIT:1> : break <EOL> c = out [ <NUM_LIT:0> : s ] <EOL> out = out [ s + <NUM_LIT:1> : ] <EOL> c = json . loads ( c ) <EOL> self . queue_json_response ( c ) <EOL> except Exception : <EOL> traceback . print_exc ( file = sys . stdout ) <EOL> self . is_connected = False <EOL> def send_tcp ( self , messages , callback ) : <EOL> """<STR_LIT>""" <EOL> out = '<STR_LIT>' <EOL> ids = [ ] <EOL> for m in messages : <EOL> method , params = m <EOL> request = json . dumps ( { '<STR_LIT:id>' : self . message_id , '<STR_LIT>' : method , '<STR_LIT>' : params } ) <EOL> self . unanswered_requests [ self . message_id ] = method , params , callback <EOL> ids . append ( self . message_id ) <EOL> if self . debug : <EOL> print "<STR_LIT>" , request <EOL> self . message_id += <NUM_LIT:1> <EOL> out += request + '<STR_LIT:\n>' <EOL> while out : <EOL> try : <EOL> sent = self . s . send ( out ) <EOL> out = out [ sent : ] <EOL> except socket . error , e : <EOL> if e [ <NUM_LIT:0> ] in ( errno . EWOULDBLOCK , errno . EAGAIN ) : <EOL> print_error ( "<STR_LIT>" ) <EOL> time . sleep ( <NUM_LIT:0.1> ) <EOL> continue <EOL> else : <EOL> traceback . print_exc ( file = sys . stdout ) <EOL> print_error ( "<STR_LIT>" ) <EOL> return None <EOL> return ids <EOL> def start_interface ( self ) : <EOL> if self . protocol in '<STR_LIT>' : <EOL> self . start_tcp ( ) <EOL> elif self . protocol in '<STR_LIT>' : <EOL> self . start_http ( ) <EOL> self . connect_event . set ( ) <EOL> def stop_subscriptions ( self ) : <EOL> for callback in self . subscriptions . keys ( ) : <EOL> callback ( self , None ) <EOL> self . subscriptions = { } <EOL> def send ( self , messages , callback ) : <EOL> sub = [ ] <EOL> for message in messages : <EOL> m , v = message <EOL> if m [ - <NUM_LIT:10> : ] == '<STR_LIT>' : <EOL> sub . append ( message ) <EOL> if sub : <EOL> with self . lock : <EOL> if self . subscriptions . get ( callback ) is None : <EOL> self . subscriptions [ callback ] = [ ] <EOL> for message in sub : <EOL> if message not in self . subscriptions [ callback ] : <EOL> self . subscriptions [ callback ] . append ( message ) <EOL> if not self . is_connected : <EOL> print_error ( "<STR_LIT>" ) <EOL> return <EOL> if self . protocol in '<STR_LIT>' : <EOL> with self . lock : <EOL> out = self . send_tcp ( messages , callback ) <EOL> else : <EOL> out = self . send_http ( messages , callback ) <EOL> return out <EOL> def parse_proxy_options ( self , s ) : <EOL> if type ( s ) == type ( { } ) : return s <EOL> if type ( s ) != type ( "<STR_LIT>" ) : return None <EOL> if s . lower ( ) == '<STR_LIT:none>' : return None <EOL> proxy = { "<STR_LIT>" : "<STR_LIT>" , "<STR_LIT:host>" : "<STR_LIT:localhost>" } <EOL> args = s . split ( '<STR_LIT::>' ) <EOL> n = <NUM_LIT:0> <EOL> if proxy_modes . count ( args [ n ] ) == <NUM_LIT:1> : <EOL> proxy [ "<STR_LIT>" ] = args [ n ] <EOL> n += <NUM_LIT:1> <EOL> if len ( args ) > n : <EOL> proxy [ "<STR_LIT:host>" ] = args [ n ] <EOL> n += <NUM_LIT:1> <EOL> if len ( args ) > n : <EOL> proxy [ "<STR_LIT:port>" ] = args [ n ] <EOL> else : <EOL> proxy [ "<STR_LIT:port>" ] = "<STR_LIT>" if proxy [ "<STR_LIT>" ] == "<STR_LIT:http>" else "<STR_LIT>" <EOL> return proxy <EOL> def stop ( self ) : <EOL> if self . is_connected and self . protocol in '<STR_LIT>' and self . s : <EOL> self . s . shutdown ( socket . SHUT_RDWR ) <EOL> self . s . close ( ) <EOL> self . is_connected = False <EOL> def is_up_to_date ( self ) : <EOL> return self . unanswered_requests == { } <EOL> def start ( self , queue = None , wait = False ) : <EOL> if not self . server : <EOL> return <EOL> self . queue = queue if queue else Queue . Queue ( ) <EOL> threading . Thread . start ( self ) <EOL> if wait : <EOL> self . connect_event . wait ( ) <EOL> def run ( self ) : <EOL> self . start_interface ( ) <EOL> if self . is_connected : <EOL> self . send ( [ ( '<STR_LIT>' , [ ELECTRUM_VERSION , PROTOCOL_VERSION ] ) ] , self . on_version ) <EOL> self . change_status ( ) <EOL> self . run_tcp ( ) if self . protocol in '<STR_LIT>' else self . run_http ( ) <EOL> self . change_status ( ) <EOL> def change_status ( self ) : <EOL> self . queue . put ( self ) <EOL> def synchronous_get ( self , requests , timeout = <NUM_LIT> ) : <EOL> queue = Queue . Queue ( ) <EOL> ids = self . send ( requests , lambda i , r : queue . put ( r ) ) <EOL> id2 = ids [ : ] <EOL> res = { } <EOL> while ids : <EOL> r = queue . get ( True , timeout ) <EOL> _id = r . get ( '<STR_LIT:id>' ) <EOL> if _id in ids : <EOL> ids . remove ( _id ) <EOL> res [ _id ] = r . get ( '<STR_LIT:result>' ) <EOL> out = [ ] <EOL> for _id in id2 : <EOL> out . append ( res [ _id ] ) <EOL> return out <EOL> if __name__ == "<STR_LIT:__main__>" : <EOL> check_certificates ( ) </s>
