def handle_tcp(self, remote): sock = self.request sock_list = [sock, remote] while True: read_list, _, _ = select(sock_list, [], []) if remote in read_list: data = safe_recv(remote, 2) if data is None: break length = bytes_to_int(data) logging.debug('receiving data from remote: {}'.format(length)) data = safe_recv(remote, length) if not data: break dec = cipher.decrypt(data) if (sock.send(dec) <= 0): break if sock in read_list: data = sock.recv(8192) if not data: break enc = cipher.encrypt(data) length = len(enc) remote.send(u16_to_bytes(length)) logging.debug('send data to server: {}'.format(length)) if (remote.send(enc) <= 0): break
def handle_tcp(self, remote): sock = self.request sock_list = [sock, remote] while 1: read_list, _, _ = select(sock_list, [], []) if remote in read_list: data = remote.recv(8192) if not data: break enc = cipher.encrypt(data) length = len(enc) logging.debug('send data to client: {}'.format(length)) sock.send(u16_to_bytes(length)) if (sock.send(enc) <= 0): break if sock in read_list: data = safe_recv(sock, 2) if data is None: break length = bytes_to_int(data) logging.debug('fetching data from client: {}'.format(length)) data = safe_recv(sock, length) if data is None: break dec = cipher.decrypt(data) logging.debug('send data to server: {}'.format(len(dec))) if (remote.send(dec) <= 0): logging.debug('send to server error') break
def handle(self): try: data = self.request.recv(1) except ConnectionResetError: logging.error('ConnectionResetError') return except Exception as e: logging.error('Error: {}'.format(e)) return if not data: return logging.info('client connected [{}]'.format(D['C'])) addr_length = data[0] data_addr = safe_recv(self.request, addr_length) if data_addr is None: return try: addr = cipher.decrypt(data_addr).decode() except: logging.error('cannot decode: {}'.format(data_addr)) return data_port = safe_recv(self.request, 2) if data_port is None: return port = bytes_to_int(data_port) logging.info("connecting to {}:{}".format(addr, port)) remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: remote.connect((addr, port)) except: logging.error('cannot connect to {}:{}'.format(addr, port)) return D['C'] += 1 logging.info("waiting for {}:{}".format(addr, port)) try: self.handle_tcp(remote) except ConnectionResetError: logging.error('ConnectionResetError [{}]'.format(D['C'])) except TimeoutError: logging.error('TimeoutError [{}]'.format(D['C'])) except Exception as e: logging.exception('Error in handle_tcp(): {} [{}]'.format( e, D['C'])) finally: remote.close() D['C'] -= 1 logging.info('client closed [{}]'.format(D['C']))
def handle(self): try: data = self.request.recv(1) except ConnectionResetError: logging.error('ConnectionResetError') return except Exception as e: logging.error('Error: {}'.format(e)) return if not data: return logging.info('client connected [{}]'.format(D['C'])) addr_length = data[0] data_addr = safe_recv(self.request, addr_length) if data_addr is None: return try: addr = cipher.decrypt(data_addr).decode() except: logging.error('cannot decode: {}'.format(data_addr)) return data_port = safe_recv(self.request, 2) if data_port is None: return port = bytes_to_int(data_port) logging.info("connecting to {}:{}".format(addr, port)) remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: remote.connect((addr, port)) except: logging.error('cannot connect to {}:{}'.format(addr, port)) return D['C'] += 1 logging.info("waiting for {}:{}".format(addr, port)) try: self.handle_tcp(remote) except ConnectionResetError: logging.error('ConnectionResetError [{}]'.format(D['C'])) except TimeoutError: logging.error('TimeoutError [{}]'.format(D['C'])) except Exception as e: logging.exception('Error in handle_tcp(): {} [{}]'.format(e, D['C'])) finally: remote.close() D['C'] -= 1 logging.info('client closed [{}]'.format(D['C']))
def handle(self): logging.info("got connection from {}".format(self.client_address[0])) data = safe_recv(self.request, 1) if data is None: return if data[0] != 5: logging.error("socks version not 5 but {}".format(data[0])) return data = safe_recv(self.request, 1) if data is None: return length = bytes_to_int(data) methods = safe_recv(self.request, length) if methods is None: return if b'\x00' not in methods: logging.error('client not support bare connect') return logging.debug('got client supported methods: {}'.format(methods)) # Send initial SOCKS5 response (VER, METHOD) self.request.sendall(b'\x05\x00') logging.debug('replied ver, method to client') data = safe_recv(self.request, 4) if data is None: logging.error('ver, cmd, rsv, atyp not received') return logging.debug('ver, cmd, rsv, atyp = {}'.format(data)) if len(data) != 4: logging.error("packet loss") return ver, cmd, rsv, atyp = data if ver != 5: logging.error('ver should be 05: {}'.format(ver)) return if cmd == 1: # CONNECT logging.info('client cmd type: connect') elif cmd == 2: # BIND logging.info('client cmd type: bind') else: logging.error('bad cmd from client: {}'.format(cmd)) return if atyp == ATYP_IPV6: logging.error('do not support IPV6 yet') return elif atyp == ATYP_DOMAIN: addr_len = ord(self.request.recv(1)) addr = self.request.recv(addr_len) elif atyp == ATYP_IPV4: addr = self.request.recv(4) addr = str(ipaddress.ip_address(addr)).encode() else: logging.error('bad atyp value: {}'.format(atyp)) return addr_port = self.request.recv(2) logging.info('want to access {}:{}'.format( addr.decode(), int.from_bytes(addr_port, 'big'))) remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: remote.connect((SERVER_IP, SERVER_PORT)) except: logging.error('cannot connect to lightsocks server.') return D['R'] += 1 logging.info('connected proxy server [{}]'.format(D['R'])) # Reply to client to estanblish the socks v5 connection reply = b"\x05\x00\x00\x01" reply += socket.inet_aton('0.0.0.0') reply += struct.pack("!H", 0) self.request.sendall(reply) # encrypt address before sending it addr = cipher.encrypt(addr) dest_address = bytearray() dest_address += len(addr).to_bytes(1, 'big') dest_address += addr dest_address += addr_port remote.sendall(dest_address) try: self.handle_tcp(remote) except Exception as e: logging.error('Got Exception: {}'.format(e)) finally: remote.close() D['R'] -= 1 logging.info('disconnected from proxy server [{}]'.format(D['R']))