From 04e88bab3cf415715dd100e2f8360c65619f9a30 Mon Sep 17 00:00:00 2001 From: Yann Leboulanger Date: Mon, 24 Nov 2008 17:00:20 +0000 Subject: [PATCH] coding standards --- src/common/socks5.py | 287 +++++++++++++++++++++---------------------- 1 file changed, 142 insertions(+), 145 deletions(-) diff --git a/src/common/socks5.py b/src/common/socks5.py index 55cdc4369..1523982e6 100644 --- a/src/common/socks5.py +++ b/src/common/socks5.py @@ -68,7 +68,7 @@ class SocksQueue: self.error_cb = error_cb self.on_success = None self.on_failure = None - + def start_listener(self, port, sha_str, sha_handler, sid): ''' start waiting for incomming connections on (host, port) and do a socks5 authentication using sid for generated sha @@ -87,16 +87,16 @@ class SocksQueue: return None self.connected += 1 return self.listener - + def send_success_reply(self, file_props, streamhost): if 'streamhost-used' in file_props and \ - file_props['streamhost-used'] is True: - if 'proxyhosts' in file_props: - for proxy in file_props['proxyhosts']: - if proxy == streamhost: - self.on_success(streamhost) - return 2 - return 0 + file_props['streamhost-used'] is True: + if 'proxyhosts' in file_props: + for proxy in file_props['proxyhosts']: + if proxy == streamhost: + self.on_success(streamhost) + return 2 + return 0 if 'streamhosts' in file_props: for host in file_props['streamhosts']: if streamhost['state'] == 1: @@ -105,22 +105,21 @@ class SocksQueue: self.on_success(streamhost) return 1 return 0 - - def connect_to_hosts(self, account, sid, on_success = None, - on_failure = None): + + def connect_to_hosts(self, account, sid, on_success=None, on_failure=None): self.on_success = on_success self.on_failure = on_failure file_props = self.files_props[account][sid] file_props['failure_cb'] = on_failure - - # add streamhosts to the queue + + # add streamhosts to the queue for streamhost in file_props['streamhosts']: receiver = Socks5Receiver(self.idlequeue, streamhost, sid, file_props) self.add_receiver(account, receiver) streamhost['idx'] = receiver.queue_idx - + def _socket_connected(self, streamhost, file_props): - ''' called when there is a host connected to one of the + ''' called when there is a host connected to one of the senders's streamhosts. Stop othere attempts for connections ''' for host in file_props['streamhosts']: if host != streamhost and 'idx' in host: @@ -130,14 +129,14 @@ class SocksQueue: return # set state -2, meaning that this streamhost is stopped, # but it may be connectected later - if host['state'] >=0: + if host['state'] >= 0: self.remove_receiver(host['idx']) host['idx'] = -1 host['state'] = -2 - + def reconnect_receiver(self, receiver, streamhost): - ''' Check the state of all streamhosts and if all has failed, then - emit connection failure cb. If there are some which are still + ''' Check the state of all streamhosts and if all has failed, then + emit connection failure cb. If there are some which are still not connected try to establish connection to one of them. ''' self.idlequeue.remove_timeout(receiver.fd) @@ -156,7 +155,8 @@ class SocksQueue: for host in file_props['streamhosts']: if host['state'] == -2: host['state'] = 0 - receiver = Socks5Receiver(self.idlequeue, host, host['sid'], file_props) + receiver = Socks5Receiver(self.idlequeue, host, host['sid'], + file_props) self.add_receiver(receiver.account, receiver) host['idx'] = receiver.queue_idx # we still have chances to connect @@ -169,7 +169,7 @@ class SocksQueue: receiver.disconnect() file_props['error'] = -1 self.process_result(-1, receiver) - + def _connection_refused(self, streamhost, file_props, idx): ''' cb, called when we loose connection during transfer''' if file_props is None: @@ -182,10 +182,10 @@ class SocksQueue: return # failure_cb exists - this means that it has never been called if 'failure_cb' in file_props and file_props['failure_cb']: - file_props['failure_cb'](streamhost['initiator'], streamhost['id'], + file_props['failure_cb'](streamhost['initiator'], streamhost['id'], file_props['sid'], code = 404) del(file_props['failure_cb']) - + def add_receiver(self, account, sock5_receiver): ''' add new file request ''' self.readers[self.idx] = sock5_receiver @@ -200,23 +200,21 @@ class SocksQueue: self.process_result(result, sock5_receiver) return 1 return None - + def get_file_from_sender(self, file_props, account): if file_props is None: return - if 'hash' in file_props and \ - file_props['hash'] in self.senders: - + if 'hash' in file_props and file_props['hash'] in self.senders: sender = self.senders[file_props['hash']] sender.account = account result = self.get_file_contents(0) self.process_result(result, sender) - + def result_sha(self, sha_str, idx): if sha_str in self.sha_handlers: props = self.sha_handlers[sha_str] props[0](props[1], idx) - + def activate_proxy(self, idx): if idx not in self.readers: return @@ -242,15 +240,14 @@ class SocksQueue: self.idlequeue.plug_idle(reader, True, False) result = reader.write_next() self.process_result(result, reader) - + def send_file(self, file_props, account): - if 'hash' in file_props and \ - file_props['hash'] in self.senders: + if 'hash' in file_props and file_props['hash'] in self.senders: sender = self.senders[file_props['hash']] file_props['streamhost-used'] = True sender.account = account if file_props['type'] == 's': - sender.file_props = file_props + sender.file_props = file_props result = sender.send_file() self.process_result(result, sender) else: @@ -258,28 +255,27 @@ class SocksQueue: file_props['last-time'] = self.idlequeue.current_time() file_props['received-len'] = 0 sender.file_props = file_props - + def add_file_props(self, account, file_props): ''' file_prop to the dict of current file_props. It is identified by account name and sid ''' - if file_props is None or \ - ('sid' in file_props) is False: + if file_props is None or ('sid' in file_props) is False: return _id = file_props['sid'] if account not in self.files_props: self.files_props[account] = {} self.files_props[account][_id] = file_props - + def remove_file_props(self, account, sid): if account in self.files_props: fl_props = self.files_props[account] if sid in fl_props: del(fl_props[sid]) - + if len(self.files_props) == 0: self.connected = 0 - + def get_file_props(self, account, sid): ''' get fil_prop by account name and session id ''' if account in self.files_props: @@ -287,14 +283,14 @@ class SocksQueue: if sid in fl_props: return fl_props[sid] return None - + def on_connection_accepted(self, sock): - sock_hash = sock.__hash__() + sock_hash = sock.__hash__() if sock_hash not in self.senders: - self.senders[sock_hash] = Socks5Sender(self.idlequeue, - sock_hash, self, sock[0], sock[1][0], sock[1][1]) + self.senders[sock_hash] = Socks5Sender(self.idlequeue, sock_hash, self, + sock[0], sock[1][0], sock[1][1]) self.connected += 1 - + def process_result(self, result, actor): ''' Take appropriate actions upon the result: [ 0, - 1 ] complete/end transfer @@ -310,9 +306,9 @@ class SocksQueue: self.complete_transfer_cb(account, actor.file_props) elif self.progress_transfer_cb is not None: self.progress_transfer_cb(actor.account, actor.file_props) - - def remove_receiver(self, idx, do_disconnect = True): - ''' Remove reciver from the list and decrease + + def remove_receiver(self, idx, do_disconnect=True): + ''' Remove reciver from the list and decrease the number of active connections with 1''' if idx != -1: if idx in self.readers: @@ -323,11 +319,11 @@ class SocksQueue: reader.disconnect() else: if reader.streamhost is not None: - reader.streamhost['state'] = -1 + reader.streamhost['state'] = -1 del(self.readers[idx]) - - def remove_sender(self, idx, do_disconnect = True): - ''' Remove sender from the list of senders and decrease the + + def remove_sender(self, idx, do_disconnect=True): + ''' Remove sender from the list of senders and decrease the number of active connections with 1''' if idx != -1: if idx in self.senders: @@ -342,13 +338,14 @@ class SocksQueue: self.listener.disconnect() self.listener = None self.connected -= 1 - + class Socks5: def __init__(self, idlequeue, host, port, initiator, target, sid): if host is not None: try: self.host = host - self.ais = socket.getaddrinfo(host, port, socket.AF_UNSPEC, socket.SOCK_STREAM) + self.ais = socket.getaddrinfo(host, port, socket.AF_UNSPEC, + socket.SOCK_STREAM) except socket.gaierror: self.ais = None self.idlequeue = idlequeue @@ -364,7 +361,7 @@ class Socks5: self.size = 0 self.remaining_buff = '' self.file = None - + def open_file_for_reading(self): if self.file is None: try: @@ -376,7 +373,7 @@ class Socks5: except IOError, e: self.close_file() raise IOError, e - + def close_file(self): if self.file: if not self.file.closed: @@ -385,7 +382,7 @@ class Socks5: except Exception: pass self.file = None - + def get_fd(self): ''' Test if file is already open and return its fd, or just open the file and return the fd. @@ -404,7 +401,7 @@ class Socks5: self.file_props['last-time'] = self.idlequeue.current_time() self.file_props['received-len'] = offset return fd - + def rem_fd(self, fd): if 'fd' in self.file_props: del(self.file_props['fd']) @@ -412,21 +409,20 @@ class Socks5: fd.close() except Exception: pass - - + def receive(self): - ''' Reads small chunks of data. + ''' Reads small chunks of data. Calls owner's disconnected() method if appropriate.''' received = '' - try: + try: add = self._recv(64) - except Exception, e: - add='' - received +=add + except Exception, e: + add = '' + received += add if len(add) == 0: self.disconnect() return add - + def send_raw(self,raw_data): ''' Writes raw outgoing data. ''' try: @@ -434,7 +430,7 @@ class Socks5: except Exception, e: self.disconnect() return len(raw_data) - + def write_next(self): if self.remaining_buff != '': buff = self.remaining_buff @@ -483,12 +479,10 @@ class Socks5: self.state = 8 # end connection self.disconnect() return -1 - + def get_file_contents(self, timeout): - ''' read file contents from socket and write them to file ''', \ - self.file_props['type'], self.file_props['sid'] - if self.file_props is None or \ - ('file-name' in self.file_props) is False: + ''' read file contents from socket and write them to file ''' + if self.file_props is None or ('file-name' in self.file_props) is False: self.file_props['error'] = -2 return None fd = None @@ -510,7 +504,7 @@ class Socks5: return 0 else: fd = self.get_fd() - try: + try: buff = self._recv(MAX_BUFF_LEN) except Exception, e: buff = '' @@ -549,7 +543,7 @@ class Socks5: if self.file_props['received-len'] != 0: return self.file_props['received-len'] return None - + def disconnect(self): ''' Closes open descriptors and remover socket descr. from idleque ''' # be sure that we don't leave open file @@ -565,12 +559,12 @@ class Socks5: self.connected = False self.fd = -1 self.state = -1 - + def _get_auth_buff(self): - ''' Message, that we support 1 one auth mechanism: + ''' Message, that we support 1 one auth mechanism: the 'no auth' mechanism. ''' return struct.pack('!BBB', 0x05, 0x01, 0x00) - + def _parse_auth_buff(self, buff): ''' Parse the initial message and create a list of auth mechanisms ''' @@ -583,30 +577,31 @@ class Socks5: except Exception: return None return auth_mechanisms + def _get_auth_response(self): ''' socks version(5), number of extra auth methods (we send 0x00 - no auth ) ''' return struct.pack('!BB', 0x05, 0x00) - + def _get_connect_buff(self): ''' Connect request by domain name ''' - buff = struct.pack('!BBBBB%dsBB' % len(self.host), - 0x05, 0x01, 0x00, 0x03, len(self.host), self.host, + buff = struct.pack('!BBBBB%dsBB' % len(self.host), + 0x05, 0x01, 0x00, 0x03, len(self.host), self.host, self.port >> 8, self.port & 0xff) return buff - + def _get_request_buff(self, msg, command = 0x01): - ''' Connect request by domain name, + ''' Connect request by domain name, sid sha, instead of domain name (jep 0096) ''' - buff = struct.pack('!BBBBB%dsBB' % len(msg), + buff = struct.pack('!BBBBB%dsBB' % len(msg), 0x05, command, 0x00, 0x03, len(msg), msg, 0, 0) return buff - + def _parse_request_buff(self, buff): try: # don't trust on what comes from the outside - version, req_type, reserved, host_type, = \ - struct.unpack('!BBBB', buff[:4]) + version, req_type, reserved, host_type, = struct.unpack('!BBBB', + buff[:4]) if host_type == 0x01: host_arr = struct.unpack('!iiii', buff[4:8]) host, = '.'.join(str(s) for s in host_arr) @@ -615,18 +610,18 @@ class Socks5: host_len, = struct.unpack('!B' , buff[4]) host, = struct.unpack('!%ds' % host_len, buff[5:5 + host_len]) portlen = len(buff[host_len + 5:]) - if portlen == 1: + if portlen == 1: port, = struct.unpack('!B', buff[host_len + 5]) - elif portlen == 2: + elif portlen == 2: port, = struct.unpack('!H', buff[host_len + 5:]) # file data, comes with auth message (Gaim bug) - else: + else: port, = struct.unpack('!H', buff[host_len + 5: host_len + 7]) self.remaining_buff = buff[host_len + 7:] except Exception: return (None, None, None) return (req_type, host, port) - + def read_connect(self): ''' connect responce: version, auth method ''' buff = self._recv() @@ -636,7 +631,7 @@ class Socks5: version, method = None, None if version != 0x05 or method == 0xff: self.disconnect() - + def continue_paused_transfer(self): if self.state < 5: return @@ -644,18 +639,20 @@ class Socks5: self.idlequeue.plug_idle(self, False, True) else: self.idlequeue.plug_idle(self, True, False) - + def _get_sha1_auth(self): ''' get sha of sid + Initiator jid + Target jid ''' if 'is_a_proxy' in self.file_props: del(self.file_props['is_a_proxy']) - return sha.new('%s%s%s' % (self.sid, self.file_props['proxy_sender'], + return sha.new('%s%s%s' % (self.sid, self.file_props['proxy_sender'], self.file_props['proxy_receiver'])).hexdigest() - return sha.new('%s%s%s' % (self.sid, self.initiator, self.target)).hexdigest() - + return sha.new('%s%s%s' % (self.sid, self.initiator, self.target)).\ + hexdigest() + class Socks5Sender(Socks5, IdleObject): ''' class for sending file to socket over socks5 ''' - def __init__(self, idlequeue, sock_hash, parent, _sock, host = None, port = None): + def __init__(self, idlequeue, sock_hash, parent, _sock, host=None, + port=None): self.queue_idx = sock_hash self.queue = parent Socks5.__init__(self, idlequeue, host, port, None, None, None) @@ -669,7 +666,7 @@ class Socks5Sender(Socks5, IdleObject): self.file_props = None # start waiting for data self.idlequeue.plug_idle(self, False, True) - + def read_timeout(self): self.idlequeue.remove_timeout(self.fd) if self.state > 5: @@ -680,9 +677,9 @@ class Socks5Sender(Socks5, IdleObject): if SEND_TIMEOUT > 0: self.idlequeue.set_read_timeout(self.fd, SEND_TIMEOUT) else: - # stop transfer, there is no error code for this + # stop transfer, there is no error code for this self.pollend() - + def pollout(self): if not self.connected: self.disconnect() @@ -696,7 +693,7 @@ class Socks5Sender(Socks5, IdleObject): if self.file_props['paused']: self.file_props['continue_cb'] = self.continue_paused_transfer self.idlequeue.plug_idle(self, False, False) - return + return result = self.write_next() self.queue.process_result(result, self) if result is None or result <= 0: @@ -712,13 +709,13 @@ class Socks5Sender(Socks5, IdleObject): self.state += 1 # unplug and plug this time for reading self.idlequeue.plug_idle(self, False, True) - + def pollend(self): self.state = 8 # end connection self.disconnect() self.file_props['error'] = -1 self.queue.process_result(-1, self) - + def pollin(self): if self.connected: if self.state < 5: @@ -727,17 +724,16 @@ class Socks5Sender(Socks5, IdleObject): self.queue.result_sha(self.sha_msg, self.queue_idx) if result == -1: self.disconnect() - + elif self.state == 5: - if self.file_props is not None and \ - self.file_props['type'] == 'r': + if self.file_props is not None and self.file_props['type'] == 'r': result = self.get_file_contents(0) self.queue.process_result(result, self) else: self.disconnect() - + def send_file(self): - ''' start sending the file over verified connection ''' + ''' start sending the file over verified connection ''' if self.file_props['started']: return self.file_props['error'] = 0 @@ -756,7 +752,7 @@ class Socks5Sender(Socks5, IdleObject): # plug for writing self.idlequeue.plug_idle(self, True, False) return self.write_next() # initial for nl byte - + def main(self): ''' initial requests for verifying the connection ''' if self.state == 1: # initial read @@ -775,8 +771,8 @@ class Socks5Sender(Socks5, IdleObject): # unplug & plug for writing self.idlequeue.plug_idle(self, True, False) return None - - def disconnect(self, cb = True): + + def disconnect(self, cb=True): ''' Closes the socket. ''' # close connection and remove us from the queue Socks5.disconnect(self) @@ -788,20 +784,20 @@ class Socks5Sender(Socks5, IdleObject): class Socks5Listener(IdleObject): def __init__(self, idlequeue, port): - ''' handle all incomming connections on (0.0.0.0, port) + ''' handle all incomming connections on (0.0.0.0, port) This class implements IdleObject, but we will expect only pollin events though ''' self.port = port self.ais = socket.getaddrinfo(None, port, socket.AF_UNSPEC, - socket.SOCK_STREAM, socket.SOL_TCP, socket.AI_PASSIVE) - self.queue_idx = -1 + socket.SOCK_STREAM, socket.SOL_TCP, socket.AI_PASSIVE) + self.queue_idx = -1 self.idlequeue = idlequeue self.queue = None self.started = False self._sock = None self.fd = -1 - + def bind(self): for ai in self.ais: #try the different possibilities (ipv6, ipv4, etc.) @@ -825,16 +821,16 @@ class Socks5Listener(IdleObject): self.fd = self._serv.fileno() self.idlequeue.plug_idle(self, False, True) self.started = True - + def pollend(self): ''' called when we stop listening on (host, port) ''' self.disconnect() - + def pollin(self): ''' accept a new incomming connection and notify queue''' sock = self.accept_conn() self.queue.on_connection_accepted(sock) - + def disconnect(self): ''' free all resources, we are not listening anymore ''' self.idlequeue.remove_timeout(self.fd) @@ -846,13 +842,13 @@ class Socks5Listener(IdleObject): self._serv.close() except Exception: pass - + def accept_conn(self): ''' accepts a new incomming connection ''' _sock = self._serv.accept() _sock[0].setblocking(False) return _sock - + class Socks5Receiver(Socks5, IdleObject): def __init__(self, idlequeue, streamhost, sid, file_props = None): self.queue_idx = -1 @@ -871,9 +867,10 @@ class Socks5Receiver(Socks5, IdleObject): self.file_props['paused'] = False self.file_props['continue_cb'] = self.continue_paused_transfer self.file_props['stalled'] = False - Socks5.__init__(self, idlequeue, streamhost['host'], int(streamhost['port']), - streamhost['initiator'], streamhost['target'], sid) - + Socks5.__init__(self, idlequeue, streamhost['host'], + int(streamhost['port']), streamhost['initiator'], streamhost['target'], + sid) + def read_timeout(self): self.idlequeue.remove_timeout(self.fd) if self.state > 5: @@ -886,11 +883,11 @@ class Socks5Receiver(Socks5, IdleObject): if READ_TIMEOUT > 0: self.idlequeue.set_read_timeout(self.fd, READ_TIMEOUT) else: - # stop transfer, there is no error code for this + # stop transfer, there is no error code for this self.pollend() else: self.queue.reconnect_receiver(self, self.streamhost) - + def connect(self): ''' create the socket and plug it to the idlequeue ''' if self.ais is None: @@ -898,10 +895,10 @@ class Socks5Receiver(Socks5, IdleObject): for ai in self.ais: try: - self._sock=socket.socket(*ai[:3]) + self._sock = socket.socket(*ai[:3]) # this will not block the GUI self._sock.setblocking(False) - self._server=ai[4] + self._server = ai[4] break except Exception: if sys.exc_value[0] == errno.EINPROGRESS: @@ -914,11 +911,12 @@ class Socks5Receiver(Socks5, IdleObject): self.do_connect() self.idlequeue.set_read_timeout(self.fd, CONNECT_TIMEOUT) return None - + def _is_connected(self): if self.state < 5: return False return True + def pollout(self): self.idlequeue.remove_timeout(self.fd) if self.state == 0: @@ -939,7 +937,7 @@ class Socks5Receiver(Socks5, IdleObject): # unplug and plug for reading self.idlequeue.plug_idle(self, False, True) self.idlequeue.set_read_timeout(self.fd, CONNECT_TIMEOUT) - + def pollend(self): if self.state >= 5: # error during transfer @@ -948,7 +946,7 @@ class Socks5Receiver(Socks5, IdleObject): self.queue.process_result(-1, self) else: self.queue.reconnect_receiver(self, self.streamhost) - + def pollin(self): self.idlequeue.remove_timeout(self.fd) if self.connected: @@ -965,10 +963,9 @@ class Socks5Receiver(Socks5, IdleObject): self.idlequeue.set_read_timeout(self.fd, STALLED_TIMEOUT) result = self.get_file_contents(0) self.queue.process_result(result, self) - else: self.disconnect() - + def do_connect(self): try: self._sock.connect(self._server) @@ -979,7 +976,7 @@ class Socks5Receiver(Socks5, IdleObject): (errnum, errstr) = ee self.connect_timeout += 1 if errnum == 111 or self.connect_timeout > 1000: - self.queue._connection_refused(self.streamhost, + self.queue._connection_refused(self.streamhost, self.file_props, self.queue_idx) return None # win32 needs this @@ -994,13 +991,13 @@ class Socks5Receiver(Socks5, IdleObject): self.file_props['connected'] = True self.file_props['disconnect_cb'] = self.disconnect self.state = 1 # connected - + # stop all others connections to sender's streamhosts self.queue._socket_connected(self.streamhost, self.file_props) self.idlequeue.plug_idle(self, True, False) return 1 # we are connected - - def main(self, timeout = 0): + + def main(self, timeout=0): ''' begin negotiation. on success 'address' != 0 ''' result = 1 buff = self.receive() @@ -1008,7 +1005,7 @@ class Socks5Receiver(Socks5, IdleObject): # end connection self.pollend() return - + if self.state == 2: # read auth response if buff is None or len(buff) != 2: return None @@ -1027,7 +1024,7 @@ class Socks5Receiver(Socks5, IdleObject): addrlen = ord(buff[4]) address = struct.unpack('!%ds' % addrlen, buff[5:addrlen + 5]) portlen = len(buff[addrlen + 5:]) - if portlen == 1: + if portlen == 1: port, = struct.unpack('!B', buff[addrlen + 5]) elif portlen == 2: port, = struct.unpack('!H', buff[addrlen + 5:]) @@ -1036,14 +1033,14 @@ class Socks5Receiver(Socks5, IdleObject): self.remaining_buff = buff[addrlen + 7:] self.state = 5 # for senders: init file_props and send '\n' if self.queue.on_success: - result = self.queue.send_success_reply(self.file_props, + result = self.queue.send_success_reply(self.file_props, self.streamhost) if result == 0: self.state = 8 self.disconnect() - - # for senders: init file_props - if result == 1 and self.state == 5: + + # for senders: init file_props + if result == 1 and self.state == 5: if self.file_props['type'] == 's': self.file_props['error'] = 0 self.file_props['disconnect_cb'] = self.disconnect @@ -1063,15 +1060,15 @@ class Socks5Receiver(Socks5, IdleObject): self.idlequeue.plug_idle(self, False, True) self.file_props['continue_cb'] = self.continue_paused_transfer # we have set up the connection, next - retrieve file - self.state = 6 + self.state = 6 if self.state < 5: self.idlequeue.plug_idle(self, True, False) self.state += 1 return None - - def disconnect(self, cb = True): + + def disconnect(self, cb=True): ''' Closes the socket. Remove self from queue if cb is True''' - # close connection + # close connection Socks5.disconnect(self) if cb is True: self.file_props['disconnect_cb'] = None