Handle socks5 request according to RFC192.
(self)
| 59 | self.conn = conn |
| 60 | |
| 61 | def handle(self): |
| 62 | """Handle socks5 request according to RFC192.""" |
| 63 | try: |
| 64 | # Verify socks version |
| 65 | ver = recvall(self.conn, 1)[0] |
| 66 | if ver != 0x05: |
| 67 | raise IOError('Invalid socks version %i' % ver) |
| 68 | # Choose authentication method |
| 69 | nmethods = recvall(self.conn, 1)[0] |
| 70 | methods = bytearray(recvall(self.conn, nmethods)) |
| 71 | method = None |
| 72 | if 0x02 in methods and self.serv.conf.auth: |
| 73 | method = 0x02 # username/password |
| 74 | elif 0x00 in methods and self.serv.conf.unauth: |
| 75 | method = 0x00 # unauthenticated |
| 76 | if method is None: |
| 77 | raise IOError('No supported authentication method was offered') |
| 78 | # Send response |
| 79 | self.conn.sendall(bytearray([0x05, method])) |
| 80 | # Read authentication (optional) |
| 81 | username = None |
| 82 | password = None |
| 83 | if method == 0x02: |
| 84 | ver = recvall(self.conn, 1)[0] |
| 85 | if ver != 0x01: |
| 86 | raise IOError('Invalid auth packet version %i' % ver) |
| 87 | ulen = recvall(self.conn, 1)[0] |
| 88 | username = str(recvall(self.conn, ulen)) |
| 89 | plen = recvall(self.conn, 1)[0] |
| 90 | password = str(recvall(self.conn, plen)) |
| 91 | # Send authentication response |
| 92 | self.conn.sendall(bytearray([0x01, 0x00])) |
| 93 | |
| 94 | # Read connect request |
| 95 | ver, cmd, _, atyp = recvall(self.conn, 4) |
| 96 | if ver != 0x05: |
| 97 | raise IOError('Invalid socks version %i in connect request' % ver) |
| 98 | if cmd != Command.CONNECT: |
| 99 | raise IOError('Unhandled command %i in connect request' % cmd) |
| 100 | |
| 101 | if atyp == AddressType.IPV4: |
| 102 | addr = recvall(self.conn, 4) |
| 103 | elif atyp == AddressType.DOMAINNAME: |
| 104 | n = recvall(self.conn, 1)[0] |
| 105 | addr = recvall(self.conn, n) |
| 106 | elif atyp == AddressType.IPV6: |
| 107 | addr = recvall(self.conn, 16) |
| 108 | else: |
| 109 | raise IOError('Unknown address type %i' % atyp) |
| 110 | port_hi,port_lo = recvall(self.conn, 2) |
| 111 | port = (port_hi << 8) | port_lo |
| 112 | |
| 113 | # Send dummy response |
| 114 | self.conn.sendall(bytearray([0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])) |
| 115 | |
| 116 | cmdin = Socks5Command(cmd, atyp, addr, port, username, password) |
| 117 | self.serv.queue.put(cmdin) |
| 118 | logger.info('Proxy: %s', cmdin) |
nothing calls this directly
no test coverage detected