<s> r'''<STR_LIT>''' <EOL> import collections <EOL> import glob <EOL> import os <EOL> import stat <EOL> import socket <EOL> import ssl <EOL> import sys <EOL> import uuid <EOL> import logging <EOL> import urllib <EOL> from OpenSSL import crypto <EOL> from nogotofail . clients . linux . pyblame import util <EOL> Application = collections . namedtuple ( "<STR_LIT>" , [ "<STR_LIT>" , "<STR_LIT:version>" ] ) <EOL> class BlameConnection ( object ) : <EOL> host = "<STR_LIT>" <EOL> port = - <NUM_LIT:1> <EOL> install_id = "<STR_LIT>" <EOL> blame_sock = None <EOL> resp_headers = { } <EOL> probability = <NUM_LIT:0> <EOL> override_attacks = True <EOL> attacks = [ ] <EOL> data_attacks = [ ] <EOL> platform_info = "<STR_LIT>" <EOL> ssl = True <EOL> fingerprint_callback = None <EOL> vuln_callback = None <EOL> info_callback = None <EOL> handshake_completed = False <EOL> def __init__ ( self , host , port , ssl = True , fingerprint_callback = None , <EOL> install_id = None , platform_info = "<STR_LIT>" , probability = None , <EOL> attacks = None , data_attacks = None , <EOL> vuln_callback = None , info_callback = None ) : <EOL> self . host = host <EOL> self . port = port <EOL> self . ssl = ssl <EOL> self . fingerprint_callback = fingerprint_callback <EOL> self . install_id = install_id or uuid . uuid4 ( ) <EOL> self . platform_info = platform_info <EOL> self . probability = probability <EOL> self . attacks = attacks <EOL> self . data_attacks = data_attacks <EOL> self . vuln_callback = vuln_callback <EOL> self . info_callback = info_callback <EOL> self . logger = logging . getLogger ( "<STR_LIT>" ) <EOL> def build_headers ( self ) : <EOL> """<STR_LIT>""" <EOL> headers = { } <EOL> headers [ "<STR_LIT>" ] = self . install_id <EOL> headers [ "<STR_LIT>" ] = self . platform_info <EOL> if self . attacks is not None : <EOL> headers [ "<STR_LIT>" ] = "<STR_LIT:U+002C>" . join ( self . attacks ) <EOL> if self . data_attacks is not None : <EOL> headers [ "<STR_LIT>" ] = "<STR_LIT:U+002C>" . join ( self . data_attacks ) <EOL> if self . probability is not None : <EOL> headers [ "<STR_LIT>" ] = self . probability <EOL> return headers <EOL> def handshake ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . blame_sock : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> headers = self . build_headers ( ) <EOL> f = self . blame_sock . makefile ( ) <EOL> f . write ( "<STR_LIT>" + <EOL> "<STR_LIT:\n>" . join ( ( "<STR_LIT>" % ( key , value ) for key , value in headers . iteritems ( ) ) ) + <EOL> "<STR_LIT>" ) <EOL> f . flush ( ) <EOL> line = f . readline ( ) . strip ( ) <EOL> if line . split ( "<STR_LIT:U+0020>" ) [ <NUM_LIT:0> ] != "<STR_LIT:0>" : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> while True : <EOL> line = f . readline ( ) . strip ( ) <EOL> if not line : <EOL> break <EOL> key , value = line . split ( "<STR_LIT::>" , <NUM_LIT:1> ) <EOL> self . resp_headers [ key . strip ( ) ] = value . strip ( ) <EOL> self . handshake_completed = True <EOL> def connect ( self ) : <EOL> """<STR_LIT>""" <EOL> sock = socket . create_connection ( ( self . host , self . port ) ) <EOL> self . logger . info ( "<STR_LIT>" ) <EOL> if self . ssl : <EOL> sock = ssl . wrap_socket ( sock ) <EOL> cert = crypto . load_certificate ( crypto . FILETYPE_ASN1 , sock . getpeercert ( True ) ) <EOL> digest = cert . digest ( "<STR_LIT>" ) <EOL> if self . fingerprint_callback and not self . fingerprint_callback ( digest ) : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> self . logger . info ( "<STR_LIT>" ) <EOL> self . blame_sock = sock <EOL> def on_vuln_notify ( self , params ) : <EOL> """<STR_LIT>""" <EOL> id , type , server_addr , server_port = params [ : <NUM_LIT:4> ] <EOL> remaining = "<STR_LIT:U+0020>" . join ( params [ <NUM_LIT:4> : ] ) <EOL> applications = remaining . split ( "<STR_LIT:U+002CU+0020>" ) <EOL> applications = [ Application ( * map ( urllib . unquote , app . split ( ) ) ) for app in applications ] <EOL> if self . vuln_callback : <EOL> self . vuln_callback ( id , type , server_addr , server_port , applications ) <EOL> return "<STR_LIT:OK>" <EOL> def on_tcp_client_id ( self , params ) : <EOL> """<STR_LIT>""" <EOL> source_port = int ( params [ <NUM_LIT:0> ] ) <EOL> dest_ip = None <EOL> dest_port = - <NUM_LIT:1> <EOL> if len ( params ) > <NUM_LIT:1> : <EOL> dest_ip_bytes = params [ <NUM_LIT:1> ] . decode ( "<STR_LIT>" ) <EOL> if len ( dest_ip_bytes ) == <NUM_LIT:4> : <EOL> family = socket . AF_INET <EOL> elif len ( dest_ip_bytes ) == <NUM_LIT:16> : <EOL> family = socket . AF_INET6 <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> dest_ip = socket . inet_ntop ( family , dest_ip_bytes ) <EOL> if len ( params ) > <NUM_LIT:2> : <EOL> dest_port = int ( params [ <NUM_LIT:2> ] ) <EOL> if self . info_callback : <EOL> applications = self . info_callback ( source_port , dest_ip , dest_port ) <EOL> if applications : <EOL> return "<STR_LIT:U+002CU+0020>" . join ( ( "<STR_LIT>" % ( urllib . quote ( app . application ) , app . version ) <EOL> for app in applications ) ) <EOL> return "<STR_LIT>" <EOL> command_handlers = { <EOL> "<STR_LIT>" : on_tcp_client_id , <EOL> "<STR_LIT>" : on_vuln_notify , <EOL> } <EOL> def run ( self ) : <EOL> """<STR_LIT>""" <EOL> if not self . handshake_completed : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> f = self . blame_sock . makefile ( ) <EOL> while True : <EOL> line = f . readline ( ) . strip ( ) <EOL> if not line : <EOL> break <EOL> params = line . split ( "<STR_LIT:U+0020>" ) <EOL> tx_id , command = params [ : <NUM_LIT:2> ] <EOL> handler = self . command_handlers . get ( command ) <EOL> reply_payload = None <EOL> if handler : <EOL> reply_payload = handler ( self , params [ <NUM_LIT:2> : ] ) <EOL> else : <EOL> reply_payload = "<STR_LIT>" <EOL> if not reply_payload : <EOL> reply_payload = "<STR_LIT>" <EOL> f . write ( "<STR_LIT>" % ( tx_id , reply_payload ) ) <EOL> f . flush ( ) </s>
