def _write_SOCKS5_address(self, addr, file): """ Return the host and port packed for the SOCKS5 protocol, and the resolved address as a tuple object. """ host, port = addr proxy_type, _, _, rdns, username, password = self.proxy # If the given destination address is an IP address, we'll # use the IPv4 address request even if remote resolving was specified. try: addr_bytes = socket.inet_aton(host) file.write(b"\x01" + addr_bytes) host = socket.inet_ntoa(addr_bytes) except socket.error: # Well it's not an IP number, so it's probably a DNS name. if rdns: # Resolve remotely host_bytes = host.encode('idna') file.write(b"\x03" + chr(len(host_bytes)).encode() + host_bytes) else: # Resolve locally addr_bytes = socket.inet_aton(socket.gethostbyname(host)) file.write(b"\x01" + addr_bytes) host = socket.inet_ntoa(addr_bytes) file.write(struct.pack(">H", port)) return host, port
def socks5_connect(sock, target, rdns=True): stream = sock.makefile() # connect request try: reqaddr = "\x01" + socket.inet_aton(target[0]) except socket.error: if rdns: reqaddr = '\x03' + fmt_string(target[0]) else: reqaddr = "\x01" + socket.inet_aton(socket.gethostbyname( target[0])) s = "\x05\x01\x00" + reqaddr + struct.pack(">H", target[1]) stream.write(s) stream.flush() # connect response resp = stream.read(4) if not resp: raise EOFError() if resp[0] != "\x05": raise GeneralProxyError(1) if resp[1] != "\x00": if ord(resp[1]) <= 8: raise Socks5Error(ord(resp[1])) else: raise Socks5Error(9) if resp[3] == "\x03": boundaddr = stream.read(stream.read(1)) elif resp[3] == "\x01": boundaddr = socket.inet_ntoa(stream.read(4)) else: raise GeneralProxyError(1) boundport = struct.unpack(">H", stream.read(2))[0] logger.debug('socks connected with %s:%s' % target) return boundaddr, boundport
def loadline(self, line): if line.find(' ') != -1: addr, mask = line.split(' ', 1) addr, mask = socket.inet_aton(addr), socket.inet_aton(mask) elif line.find('/') != -1: addr, mask = line.split('/', 1) addr, mask = socket.inet_aton(addr), makemask(int(mask)) self.nets.setdefault(mask, set()) self.nets[mask].add(get_netaddr(addr, mask))
def init_headers(self, ip_src=SRC_IP, ip_dst=DST_IP, src_port=SRC_PORT, dst_port=DST_PORT): # build ETH header self.eth_header = EtherFrame(dest_mac=self.DEST_MAC, src_mac=self.SRC_MAC) # build IP header self.ip_header = IPFrame(ip_src_addr=socket.inet_aton(ip_src), ip_dest_addr=socket.inet_aton(ip_dst)) # build UDP header self.udp_header = UDPFrame(src_port, dst_port)
def get_ip_version(ip): # CR: http://stackoverflow.com/questions/11827961/checking-for-ip-addresses try: socket.inet_aton(ip) return 4 except socket.error: pass try: socket.inet_pton(socket.AF_INET6, ip) return 6 except socket.error: pass raise ValueError(ip)
def gethostbyname(self, name): try: socket.inet_aton(name) return name except socket.error: pass if name in self.cache: if time.time() <= self.cache[name][0]: return random.choice(self.cache[name][1]) else: del self.cache[name] self.query(name) r = self.cache.get(name) if r is None: return None else: return random.choice(r[1])
def socks5_connect(target, proxy, username=None, password=None, rdns=True): sock = socket.socket() sock.connect(proxy) stream = sock.makefile() # hand shake request if username is None or password is None: stream.write("\x05\x01\x00") else: stream.write("\x05\x02\x00\x02") stream.flush() # hand shake response chosenauth = stream.read(2) if chosenauth[0] != "\x05": raise GeneralProxyError(1) if chosenauth[1] == "\x00": pass elif chosenauth[1] == "\x02": stream.write('\x01' + fmt_string(username) + fmt_string(password)) stream.flush() authstat = stream.read(2) if authstat[0] != "\x01": raise GeneralProxyError(1) if authstat[1] != "\x00": raise Socks5AuthError(3) logger.debug('authenticated with password') elif chosenauth[1] == "\xFF": raise Socks5AuthError(2) else: raise GeneralProxyError(1) # connect request try: reqaddr = "\x01" + socket.inet_aton(target[0]) except socket.error: if rdns: reqaddr = '\x03' + fmt_string(target[0]) else: reqaddr = "\x01" + socket.inet_aton(socket.gethostbyname(target[0])) s = "\x05\x01\x00" + reqaddr + struct.pack(">H", target[1]) stream.write(s) stream.flush() # connect response resp = stream.read(4) if not resp: raise EOFError() if resp[0] != "\x05": raise GeneralProxyError(1) if resp[1] != "\x00": if ord(resp[1]) <= 8: raise Socks5Error(ord(resp[1])) else: raise Socks5Error(9) if resp[3] == "\x03": boundaddr = stream.read(stream.read(1)) elif resp[3] == "\x01": boundaddr = socket.inet_ntoa(stream.read(4)) else: raise GeneralProxyError(1) boundport = struct.unpack(">H", stream.read(2))[0] logger.debug('connected with %s:%s, bind in %s:%d' % ( target[0], target[1], boundaddr, boundport)) return sock, (boundaddr, boundport)
def listen(self): self._sock = sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) try: sock.bind(('', self._port)) except socket.error as e: if e.errno==48: self._port += 1 return self.listen() mreq = struct.pack("4sl", socket.inet_aton(self._group), socket.INADDR_ANY) sock.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, mreq) sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, 1) sock.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP, 1) while not self._shutdown: try: data, addr = sock.recvfrom(1024) command, data = data.decode('ascii').split(SEPARATOR, 1) except Exception: continue if command in self._callbacks: response_cmd = "{0}_response".format(command) for callback in self._callbacks[command]: result = callback(data, addr) if result is not None: msg = SEPARATOR.join((response_cmd, result)) sock.sendto(msg.encode('ascii'), addr)
def echo_socket(ws): app.total += 1 server_sock = handshake(ws) if server_sock: sock_name = server_sock.getsockname() server_hex_addr = socket.inet_aton(sock_name[0]) send_msg = b'\x05\x00\x00\x01' + server_hex_addr + struct.pack(">H", sock_name[1]) ws.send(send_msg) forwarders = (gevent.spawn(ws_remote, ws, server_sock), gevent.spawn(local_ws, ws, server_sock)) gevent.joinall(forwarders) else: try: send_msg = struct.pack("!BBBBIH", 5, 5, 0, 1, 0, 0) # print('not good') ws.send(send_msg) ws.close() app.total -= 1 # print(F'total = {app.total}') return except Exception as e: app.total -= 1 # print(F'total = {app.total}') return ws.close() gc.collect() app.total -= 1
def set_acl(self, value): if isinstance(value, str): value = value.replace(' ', '').split(',') self.check_type('acl', value, list) pairs = [] for fragment in value: if not isinstance(fragment, str): raise ConfigError("Invalid acl fragment %r in %r." % (fragment, self)) if '/' in fragment: fragment, rest = fragment.split('/', 1) try: size = int(rest) except ValueError: raise ConfigError("Invalid acl mask size %r in %r." % (rest, self)) if not 0 <= size <= 32: raise ConfigError("Invalid acl mask size %r in %r." % (size, self)) else: size = 32 try: text = socket.inet_aton(fragment) except socket.error: raise ConfigError("Invalid acl IP address %r in %r." % (fragment, self)) check = struct.unpack('!I', text)[0] mask = (1 << 32) - (1 << 32 - size) pairs.append((check, mask)) self.acl = pairs
def handle(self, sock, addr): print 'connection from %s:%s' % addr src = XSocket(socket = sock, secure = True) #socks5 negotiation step2: specify command and destination ver, cmd, rsv, atype = src.unpack('BBBB', 4) if cmd != 0x01: src.pack('BBBBIH', 0x05, 0x07, 0x00, 0x01, 0, 0) return if atype == 0x01: #ipv4 host, port = src.unpack('!IH', 6) hostip = socket.inet_ntoa(struct.pack('!I', host)) elif atype == 0x03: #domain name length = src.unpack('B', 1)[0] hostname, port = src.unpack("!%dsH" % length, length + 2) hostip = gethostbyname(hostname) host = struct.unpack("!I", socket.inet_aton(hostip))[0] elif atype == 0x04: #ipv6: TODO src.pack('!BBBBIH', 0x05, 0x07, 0x00, 0x01, 0, 0) return else: src.pack('!BBBBIH', 0x05, 0x07, 0x00, 0x01, 0, 0) return try: dest = XSocket(addr = (hostip, port)) except IOError, ex: print "%s:%d" % addr, "failed to connect to %s:%d" % (hostip, port) src.pack('!BBBBIH', 0x05, 0x03, 0x00, 0x01, host, port) return
def _run(self): MCAST_GRP = '224.1.1.1' MCAST_PORT = 8001 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(('', MCAST_PORT)) mreq = struct.pack("=4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY) s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) self._ready.set() while not self._complete.is_set(): try: data, address = s.recvfrom(1024) t = data.split('|') if t[0] == 'V': self._manager.vms[t[1]] = time.time()*100 else: self._manager.ternimals[t[1]] = int(time.time())*100 print (t[0], t[1], address[0]) except : self._complete.wait(timeout=1) continue
def create_remote_connection_pipe(self, address, port, sock): """ :param address: 远程地址 :param port: 远程端口 :param sock: 本地连接的sock :return: """ remote = None try: remote = self.remote_pool.get(host=address, port=port) if self.remote_pool.too_old(remote): self.remote_pool.release_connection(remote) remote = self.remote_pool.get(host=address, port=port) reply = b"\x05\x00\x00\x01" + socket.inet_aton(address) + \ struct.pack(">H", port) sock.send(reply) log('Begin data, %s:%s' % (address, port)) # 3. 协程监听sock读写 l1 = spawn(handle_tcp, sock, remote) l2 = spawn(handle_tcp, remote, sock) gevent.joinall((l1, l2)) except socket.error as error: log('Conn refused, %s:%s' % (address, port)) # Connection refused reply = b'\x05\x05\x00\x01\x00\x00\x00\x00\x00\x00' sock.send(reply) raise error finally: if remote is not None: self.remote_pool.release_connection(remote)
def intAddress(self,Address): '''returns ip address in integer format''' if Address == '': return '' try: return struct.unpack("!I", socket.inet_aton(Address))[0] except: return Address
def __contains__(self, addr): try: addr = socket.inet_aton(addr) except TypeError: pass for mask, addrs in self.nets.iteritems(): if get_netaddr(addr, mask) in addrs: return True return False
def intAddress(self, Address): """returns ip address in integer format""" if Address == "": return "" try: return struct.unpack("!I", socket.inet_aton(Address))[0] except: return Address
def _is_valid_ipv4(address): log.debug("checking ipv4 address: %s", address) address = str(address) try: addr = socket.inet_aton(address) except socket.error: return False return address.count('.') == 3 return True
def handle(self, sock, address): rfile = sock.makefile('rb', -1) try: log('socks connection from ' + str(address)) # 1. Version sock.recv(262) sock.send(b"\x05\x00") # 2. Request data = rfile.read(4) mode = ord(data[1]) addrtype = ord(data[3]) if addrtype == 1: # IPv4 addr = socket.inet_ntoa(rfile.read(4)) elif addrtype == 3: # Domain name domain = rfile.read(ord(sock.recv(1)[0])) addr = self.handle_dns(domain) port = struct.unpack('>H', rfile.read(2)) if mode == 1: # 1. Tcp connect try: remote = self.remote_pool.get(host=addr, port=port[0]) reply = b"\x05\x00\x00\x01" + socket.inet_aton(addr) + \ struct.pack(">H", port[0]) sock.send(reply) log('Begin data, %s:%s' % (addr, port[0])) # 3. Transfering l1 = spawn(self.handle_tcp, sock, remote) l2 = spawn(self.handle_tcp, remote, sock) gevent.joinall((l1, l2)) self.remote_pool.release_connection(remote) except socket.error: log('Conn refused, %s:%s' % (addr, port[0])) # Connection refused reply = b'\x05\x05\x00\x01\x00\x00\x00\x00\x00\x00' sock.send(reply) raise else: reply = b"\x05\x07\x00\x01" # Command not supported sock.send(reply) except socket.error: pass finally: log("Close handle") rfile.close() sock._sock.close() sock.close()
def init_nflow_dicts(vips_file, vips_pps, vips_flags, vips_baseline, vips_multiplier, vips_map): for vip in vips_file: vip = vip.strip() vip = vip.split() if len(vip) != 2: sys.exit("vips file must be in format <vip> -- <baseline>") vip_net = socket.inet_aton(vip[0]) vip_int = struct.unpack('!L',vip_net)[0] vips_pps[vip_int] = 0 vips_flags[vip_int] = 0 vips_baseline[vip_int] = 0 vips_multiplier[vip_int] = int(vip[1]) vips_map[vip_int] = vip[0]
def handle_connection_made(self): _BaseConnection.handle_connection_made(self) self.send_message('NOTICE', 'AUTH', '*** sbncng 0.1 - (c) 2011 Gunnar Beutner') self.send_message('NOTICE', 'AUTH', '*** Welcome to the brave new world.') try: self.send_message('NOTICE', 'AUTH', '*** Looking up your hostname') # TODO: need to figure out how to do IPv6 reverse lookups result = dns.resolve_reverse(socket.inet_aton(self.me.host)) self.me.host = result[1] self.send_message('NOTICE', 'AUTH', '*** Found your hostname (%s)' % (self.me.host)) except dns.DNSError: self.send_message('NOTICE', 'AUTH', '*** Couldn\'t look up your hostname, using ' + \ 'your IP address instead (%s)' % (self.me.host))
def socks5_connect(sock, target, rdns=True): stream = sock.makefile() # connect request try: reqaddr = "\x01" + socket.inet_aton(target[0]) except socket.error: if rdns: reqaddr = '\x03' + fmt_string(target[0]) else: reqaddr = "\x01" + socket.inet_aton(socket.gethostbyname(target[0])) s = "\x05\x01\x00" + reqaddr + struct.pack(">H", target[1]) stream.write(s) stream.flush() # connect response resp = stream.read(4) if not resp: raise EOFError() if resp[0] != "\x05": raise GeneralProxyError(1) if resp[1] != "\x00": if ord(resp[1]) <= 8: raise Socks5Error(ord(resp[1])) else: raise Socks5Error(9) if resp[3] == "\x03": boundaddr = stream.read(stream.read(1)) elif resp[3] == "\x01": boundaddr = socket.inet_ntoa(stream.read(4)) else: raise GeneralProxyError(1) boundport = struct.unpack(">H", stream.read(2))[0] logger.debug('socks connected with %s:%s' % target) return boundaddr, boundport
def connect_target_server_and_reply(self, client_sock, addr, port, cmd): sock_name = client_sock.getsockname() server_hex_addr = socket.inet_aton(sock_name[0]) server_hex_port = self.port_to_hex_string(sock_name[1]) server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: server_sock.connect((addr, port)) send_msg = '\x05\x00\x00\x01' + server_hex_addr + server_hex_port client_sock.send(send_msg) except Exception: send_msg = '\x05\x01\x00\x01' + server_hex_addr + server_hex_port client_sock.send(send_msg) self.close_sock_and_exit(client_sock) return server_sock
def handle(self, sock, addr): print 'connection from %s:%s' % addr src = XSocket(socket = sock) #socks5 negotiation step1: choose an authentication method ver, n_method = src.unpack('BB', 2) if ver != 0x05: src.pack('BB', 0x05, 0xff) return if n_method > 0: src.recv(n_method) src.pack('!BB', 0x05, 0x00) #0x00 means no authentication needed #socks5 negotiation step2: specify command and destination ver, cmd, rsv, atype = src.unpack('BBBB', 4) if cmd != 0x01: src.pack('BBBBIH', 0x05, 0x07, 0x00, 0x01, 0, 0) return if atype == 0x01: #ipv4 host, port = src.unpack('!IH', 6) hostip = socket.inet_ntoa(struct.pack('!I', host)) elif atype == 0x03: #domain name length = src.unpack('B', 1)[0] hostname, port = src.unpack("!%dsH" % length, length + 2) hostip = gethostbyname(hostname) host = struct.unpack("!I", socket.inet_aton(hostip))[0] elif atype == 0x04: #ipv6: TODO src.pack('!BBBBIH', 0x05, 0x07, 0x00, 0x01, 0, 0) return else: src.pack('!BBBBIH', 0x05, 0x07, 0x00, 0x01, 0, 0) return try: print "call proxy, host:", hostip, port dest = SmartSocket(addr = (hostip, port)) except IOError, ex: print "%s:%d" % addr, "failed to connect to %s:%d" % (hostip, port) src.pack('!BBBBIH', 0x05, 0x03, 0x00, 0x01, host, port) return
def is_private_ip(ip): if ip.startswith('127'): return True else: ip1 = 167772160 ip2 = 2886729728 ip3 = 3232235520 binaryIp = socket.inet_aton(ip) numIp = struct.unpack('!L', binaryIp)[0] mark = 2**32 - 1 ag = (mark << 16) & numIp if ip3 == ag: return True ag = mark << 20 & numIp if ip2 == ag: return True ag = (mark << 24) & numIp if ip1 == ag: return True return False
def _initSocket(self): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) # Reuse socket in `TIME_WAIT` state (do not wait for natural timeout) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('', 1900)) # 8-byte packed rep of hte multicast group address followed by ## the network interface on which to listen ## (239.255.255.250 - IPv4 SSDP address) ## (INADDR_ANY = any interface) mreq = struct.pack("=4sl", socket.inet_aton("239.255.255.250"), socket.INADDR_ANY) # Receive packets on the network @ the group address sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) # Close the connection atexit (__del__ GC isn't guaranteed in gevent) def _closeSock(): sock.close() atexit.register(_closeSock) self.sock = sock
def socks_handler(conn, address): client_hello = conn.recv(2) if not client_hello: return version, n_methods = struct.unpack("!BB", client_hello) assert version == SOCKS_VERSION conn.recv(n_methods) conn.sendall(struct.pack("!BB", SOCKS_VERSION, 0x00)) request_header = conn.recv(4) if len(request_header) != 4: return version, cmd, addr_type = struct.unpack("!BBxB", request_header) if cmd != 0x01: raise ValueError("invalid or unsupported command") if addr_type == 0x01: buf = conn.recv(4) request_header += buf dest_addr = str(ipaddress.IPv4Address(buf)) elif addr_type == 0x04: buf = conn.recv(16) request_header += buf dest_addr = str(ipaddress.IPv6Address(buf)) elif addr_type == 0x03: size = conn.recv(1)[0] buf = conn.recv(size) request_header += struct.pack("!B", size) request_header += buf try: dest_addr = socket.gethostbyname(buf.decode()) addr_type = 0x01 except socket.gaierror as err: logging.info(err) logging.info(f"while attempting to resolve {buf.decode()}") request_header += conn.recv(2) reply = struct.pack("!BBBBB", SOCKS_VERSION, 0x04, 0x00, 0x03, size) + buf + request_header[-2:] conn.sendall(reply) return else: raise ValueError("invalid addr_type") request_header += conn.recv(2) dest_port = struct.unpack("!H", request_header[-2:])[0] do_proxy = False if PROXY_RKN and addr_type == 0x01: do_proxy |= dest_addr in BLOCKLIST do_proxy |= dest_port in PROXY_PORTS if do_proxy: upstream = socket.socket(socket.AF_INET, socket.SOCK_STREAM) upstream.connect((UPSTREAM_HOST, UPSTREAM_PORT)) upstream.sendall(struct.pack("!BBB", SOCKS_VERSION, 1, 0x00)) version, auth_mode = upstream.recv(2) assert version == SOCKS_VERSION assert auth_mode == 0x00 upstream.sendall(request_header) exchange_loop(conn, upstream) upstream.close() conn.close() else: remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM) remote.connect((dest_addr, dest_port)) bind_address, bind_port = remote.getsockname() bind_address = struct.unpack("!I", socket.inet_aton(bind_address))[0] reply = struct.pack("!BBBBIH", SOCKS_VERSION, 0, 0, addr_type, bind_address, bind_port) conn.sendall(reply) data = exchange_loop(conn, remote, dest_port == 443) if data: remote.close() # Upgrade to upstream upstream = socket.socket(socket.AF_INET, socket.SOCK_STREAM) upstream.connect((UPSTREAM_HOST, UPSTREAM_PORT)) upstream.sendall(struct.pack("!BBB", SOCKS_VERSION, 1, 0x00)) version, auth_mode = upstream.recv(2) assert version == SOCKS_VERSION assert auth_mode == 0x00 upstream.sendall(request_header) upstream.recv(10) # skip socks response upstream.sendall(data) exchange_loop(conn, upstream) upstream.close() conn.close()
def valid_ip(address): try: ip_bytes = socket.inet_aton(address) return ip_bytes except: return False
def ip2int(addr): return struct.unpack("!I", socket.inet_aton(addr))[0]
def _negotiate_SOCKS4(self, dest_addr, dest_port): """ Negotiates a connection through a SOCKS4 server. """ proxy_type, addr, port, rdns, username, password = self.proxy writer = self.makefile("wb") reader = self.makefile("rb", 0) # buffering=0 renamed in Python 3 try: # Check if the destination address provided is an IP address remote_resolve = False try: addr_bytes = socket.inet_aton(dest_addr) except socket.error: # It's a DNS name. Check where it should be resolved. if rdns: addr_bytes = b"\x00\x00\x00\x01" remote_resolve = True else: addr_bytes = socket.inet_aton( socket.gethostbyname(dest_addr)) # Construct the request packet writer.write(struct.pack(">BBH", 0x04, 0x01, dest_port)) writer.write(addr_bytes) # The username parameter is considered userid for SOCKS4 if username: writer.write(username) writer.write(b"\x00") # DNS name if remote resolving is required # NOTE: This is actually an extension to the SOCKS4 protocol # called SOCKS4A and may not be supported in all cases. if remote_resolve: writer.write(dest_addr.encode('idna') + b"\x00") writer.flush() # Get the response from the server resp = self._readall(reader, 8) if resp[0:1] != b"\x00": # Bad data raise GeneralProxyError( "SOCKS4 proxy server sent invalid data") status = ord(resp[1:2]) if status != 0x5A: # Connection failed: server returned an error error = SOCKS4_ERRORS.get(status, "Unknown error") raise SOCKS4Error("{0:#04x}: {1}".format(status, error)) # Get the bound address/port self.proxy_sockname = (socket.inet_ntoa(resp[4:]), struct.unpack(">H", resp[2:4])[0]) if remote_resolve: self.proxy_peername = socket.inet_ntoa(addr_bytes), dest_port else: self.proxy_peername = dest_addr, dest_port finally: reader.close() writer.close()
def broadcast_service(self): if self.listen_address == '0.0.0.0': raise Exception('NetRNG server: zeroconf currently requires a specific listen address in /etc/netrng.conf') desc = {'version': __version__} info = ServiceInfo('_netrng._tcp.local.', '{}._netrng._tcp.local.'.format(socket.gethostname()), socket.inet_aton(self.listen_address), self.port, 0, 0, desc) log.info('NetRNG server: registering service with Bonjour: %s', info) self.zeroconf_controller.register_service(info)
def accept(cls,network,sock,addr): logger.info('+client '+addr[0]) connection = ClientConnection.spawn(sock) serveruid = network.local.uid sendraw = connection.send name = dname = None username = None hostname = addr[0] realname = None usermode = 0 password = '' client = None try: ip = socket.inet_aton(hostname) try: # rDNS [and identd] with Timeout(4,False): hostname = dns.resolve_reverse(ip)[1] except (dns.DNSError,IndexError): pass for line in connection: # pre-registration loop try: arg,txt = line.split(':',1) except ValueError: arg = line.split() else: arg = arg.split() arg.append(txt) try: cmd = arg[0].lower() except IndexError: continue else: if cmd == 'pass': password = arg[1] elif cmd == 'nick': dname = arg[1] if cls.re_nick.match(dname) or dname[0] in '-0123456789': ex = IRCError.ErroneousNickname sendraw(':%s %s'%(serveruid,'%03d %s :%s'%(ex.code,dname,ex.message))) else: try: name = network.reserve_nick(dname[:cls.len_nick]) except KeyError: ex = IRCError.NicknameInUse sendraw(':%s %s'%(serveruid,'%03d %s :%s'%(ex.code,dname,ex.message))) elif cmd == 'user': username = cls.re_user.sub('',arg[1]) if username[0] in '-0123456789': username = '******'+username username = username[:cls.len_user] if len(username) < 1: username = ('~'+hexlify(ip).upper())[:cls.len_user-1] try: usermode = int(arg[2]) except ValueError: usermode = 0 realname = arg[3][:64] if None not in (name,username,realname): break else: connection.kill() logger.info('-client '+addr[0]) return except GreenletExit: pass except: logger.exception('oops') connection.kill() logger.info('-client '+addr[0]) else: client = cls(network,connection,name,username,hostname,realname,usermode,password) # FIXME: user mode client.start_later(0) network.client_add(client) logger.info('=client %s %s'%(addr[0],client.prefix))
def inet_aton(hostip): return struct.unpack("!I", socket.inet_aton(hostip))[0] class ConnectionException(Exception): pass
def ip_to_int(self, ip): return struct.unpack( 'I', struct.pack('I', (socket.ntohl( struct.unpack('I', socket.inet_aton(ip))[0]))))[0]
def handle(self, source, address): ''' 1. parse browser socks5 message 2. establishes WebSocket connection to a remote server 3. encrypt data using RC4 4. forward with both the local and remote server ''' log('New connection from %s:%s' % address) log('greenlet is %r', gevent.getcurrent()) rfile = source.makefile('rb', -1) try: recvcount = source.recv(262) log("recv count: %r: %r " % (recvcount, type(recvcount))) source.send(b'\x05\x00') wsdata = '' data = rfile.read(4) log('second pack %r: %r' % (type(data), data)) cmd = ord(data[1]) # CMD addrtype = ord(data[3]) # ADDR type 0x01 Ipv4 address wsdata = data[3] # append type of address if addrtype == 1: # IPv4 addrStr = rfile.read(4) addr = socket.inet_ntoa(addrStr) wsdata += addrStr elif addrtype == 3: # Domain name domainlen = ord(rfile.read(1)[0]) domain = rfile.read(domainlen) log('domain len and name: %d %s' % (domainlen, domain)) # addr = handle_dns(domain) addr = socket.inet_ntoa('\x00\x00\x00\x00') # 16777343 wsdata += chr(domainlen) wsdata += domain portstr = rfile.read(2) port = struct.unpack('>H', portstr) wsdata += portstr # append port if cmd == 1: reply = b"\x05\x00\x00\x01" + socket.inet_aton( addr) + struct.pack(">H", port[0]) log("send replay %r" % reply) source.send(reply) log('Begin data, %s:%s' % (addr, port[0])) ws = WebSocketClient(self.remotehost, protocols=['binary']) try: # gevent.monkey 阻塞 ws.connect() log("connect remote websocket server!") log('send data %r:%r:%r' % (wsdata, type(wsdata), len(wsdata))) encryptor = RC4(self.key) generator = encryptor.encrypter() out = '' for wc in wsdata: out += chr((ord(wc) ^ generator.next())) # send socks5 message ws.send(out, True) l1 = gevent.spawn(self.forward, source, ws, generator) l2 = gevent.spawn(self.incoming, ws, source) gevent.joinall([l1, l2]) except socket.error as e: log('Conn refused, %s:%s:%s' % (addr, port[0], e.message)) # Connection refused reply = b'\x05\x05\x00\x01\x00\x00\x00\x00\x00\x00' source.send(reply) raise e finally: log('close websocket: ---------------------------') ws.close() else: log('Unsupported cmd: %r' % cmd) reply = b"\x05\0x07\0x00\0x01" source.send(reply) except socket.error, (value, message): log('socks_handle socket error, %s' % (message))
def create_connection(self, address, timeout=5): startTime = int(time.time() * 1000) hostname = address[0] port = address[1] try: _sock = self.upstream.create_connection((self.socks5_hostname, self.socks5_port), timeout,) except: info = traceback.format_exc() tcpping = int(time.time() * 1000) - startTime logging.warn(u'[socks5] 远程代理服务器连接失败! socks5_hostname:%s ,socks5_port:%s ,timeout:%s,time:%s' % ( self.socks5_hostname, self.socks5_port, timeout, tcpping)) logging.warn('%s\r\n\r\n' % info) raise raise _sock.setsockopt(_socket.IPPROTO_TCP, _socket.TCP_NODELAY, 1) _sock.settimeout(timeout * 2) tcpping = int(time.time() * 1000) - startTime logging.debug(u'[socks5] 远程代理服务器已连接 socks5_hostname:%s ,socks5_port:%s ,timeout:%s,time:%s' % ( self.socks5_hostname, self.socks5_port, timeout, tcpping)) # 登录 _sock.pack('BBB', 0x05, 0x01, 0x00) # 登录回应 ver, method = _sock.unpack( 'BB') tcpping = int(time.time() * 1000) - startTime if ver != 0x05 or method != 0x00: _sock.close(safe=False) ms = u'[socks5] 远程代理服务器登录失败! host:%s ,port:%s, time:%s' % (self.socks5_hostname, self.socks5_port, tcpping) raise UpstreamLoginError(ms) logging.debug( u'[socks5] 远程代理服务器登陆成功。 host:%s ,port:%s ,time:%s' % (self.socks5_hostname, self.socks5_port, tcpping)) # 请求连接 atyp = dnslib.get_addr_type(hostname) if atyp == 0x01: # ipv4 _sock.pack('!BBBBIH', 0x05, 0x01, 0x00, atyp, struct.unpack('!I', _socket.inet_aton(hostname))[0], port) elif atyp == 0x03: # 域名 _sock.pack('!BBBBB%ssH' % len(hostname), 0x05, 0x01, 0x00, atyp, len(hostname), hostname, port) elif atyp == 0x04: # ipv6 _str = _socket.inet_pton(_socket.AF_INET6, hostname) a, b = struct.unpack('!2Q', _str) _sock.pack('!BBBB2QH', 0x05, 0x01, 0x00, atyp, a, b, port) else: tcpping = int(time.time() * 1000) - startTime ms = u'[socks5] 地址类型未知! atyp:%s ,time:%s' % (atyp, tcpping) _sock.close(safe=False) assert False, ms # 请求回应 ver, rep, rsv, atyp = _sock.unpack('BBBB') if ver != 0x05: _sock.close(safe=False) raise UpstreamProtocolError(u'未知的服务器协议版本!') if rep != 0x00: tcpping = int(time.time() * 1000) - startTime ms = u'[socks5] 远程代理服务器无法连接目标网站! ver:%s ,rep:%s, time=%s' % (ver, rep, tcpping) _sock.close(safe=False) raise _socket.error(10060, (u'[Socks5] 代理服务器无法连接到目的主机。socks5_host = %s, ' u'socks5_port = %s ,host = %s ,port = %s ,rep = %s') % (self.socks5_hostname, self.socks5_port, hostname, port, rep)) if atyp == 0x01: _sock.unpack('!IH') elif atyp == 0x03: length = _sock.unpack('B') _sock.unpack('%ssH' % length) elif atyp == 0x04: _sock.unpack('!2QH') tcpping = int(time.time() * 1000) - startTime # TODO: 这里需要记录下本sock连接远程的耗时。 return self.socket(_sock=_sock)
def create_connection(self, address, timeout=5): startTime = int(time.time() * 1000) hostname = address[0] port = address[1] try: _sock = self.upstream.create_connection( (self.socks5_hostname, self.socks5_port), timeout, ) except: info = traceback.format_exc() tcpping = int(time.time() * 1000) - startTime logging.warn( u'[socks5] 远程代理服务器连接失败! socks5_hostname:%s ,socks5_port:%s ,timeout:%s,time:%s' % (self.socks5_hostname, self.socks5_port, timeout, tcpping)) logging.warn('%s\r\n\r\n' % info) raise raise _sock.setsockopt(_socket.IPPROTO_TCP, _socket.TCP_NODELAY, 1) _sock.settimeout(timeout * 2) tcpping = int(time.time() * 1000) - startTime logging.debug( u'[socks5] 远程代理服务器已连接 socks5_hostname:%s ,socks5_port:%s ,timeout:%s,time:%s' % (self.socks5_hostname, self.socks5_port, timeout, tcpping)) # 登录 _sock.pack('BBB', 0x05, 0x01, 0x00) # 登录回应 ver, method = _sock.unpack('BB') tcpping = int(time.time() * 1000) - startTime if ver != 0x05 or method != 0x00: _sock.close(safe=False) ms = u'[socks5] 远程代理服务器登录失败! host:%s ,port:%s, time:%s' % ( self.socks5_hostname, self.socks5_port, tcpping) raise UpstreamLoginError(ms) logging.debug(u'[socks5] 远程代理服务器登陆成功。 host:%s ,port:%s ,time:%s' % (self.socks5_hostname, self.socks5_port, tcpping)) # 请求连接 atyp = dnslib.get_addr_type(hostname) if atyp == 0x01: # ipv4 _sock.pack('!BBBBIH', 0x05, 0x01, 0x00, atyp, struct.unpack('!I', _socket.inet_aton(hostname))[0], port) elif atyp == 0x03: # 域名 _sock.pack('!BBBBB%ssH' % len(hostname), 0x05, 0x01, 0x00, atyp, len(hostname), hostname, port) elif atyp == 0x04: # ipv6 _str = _socket.inet_pton(_socket.AF_INET6, hostname) a, b = struct.unpack('!2Q', _str) _sock.pack('!BBBB2QH', 0x05, 0x01, 0x00, atyp, a, b, port) else: tcpping = int(time.time() * 1000) - startTime ms = u'[socks5] 地址类型未知! atyp:%s ,time:%s' % (atyp, tcpping) _sock.close(safe=False) assert False, ms # 请求回应 ver, rep, rsv, atyp = _sock.unpack('BBBB') if ver != 0x05: _sock.close(safe=False) raise UpstreamProtocolError(u'未知的服务器协议版本!') if rep != 0x00: tcpping = int(time.time() * 1000) - startTime ms = u'[socks5] 远程代理服务器无法连接目标网站! ver:%s ,rep:%s, time=%s' % ( ver, rep, tcpping) _sock.close(safe=False) raise _socket.error( 10060, (u'[Socks5] 代理服务器无法连接到目的主机。socks5_host = %s, ' u'socks5_port = %s ,host = %s ,port = %s ,rep = %s') % (self.socks5_hostname, self.socks5_port, hostname, port, rep)) if atyp == 0x01: _sock.unpack('!IH') elif atyp == 0x03: length = _sock.unpack('B') _sock.unpack('%ssH' % length) elif atyp == 0x04: _sock.unpack('!2QH') tcpping = int(time.time() * 1000) - startTime # TODO: 这里需要记录下本sock连接远程的耗时。 return self.socket(_sock=_sock)