diff options
author | Nick Mathewson <nickm@torproject.org> | 2006-09-22 00:43:55 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2006-09-22 00:43:55 +0000 |
commit | 213658f117f88eaeb21ffd61451155f451f67604 (patch) | |
tree | 31f4c5d408f6372cc08d1be2731f4c2ab10eced9 /contrib/tor-resolve.py | |
parent | 9bc8d69dfc4ddda5a9c8478b1f1e04490845ded0 (diff) | |
download | tor-213658f117f88eaeb21ffd61451155f451f67604.tar.gz tor-213658f117f88eaeb21ffd61451155f451f67604.zip |
r8894@Kushana: nickm | 2006-09-21 18:30:42 -0400
Specify and implement SOCKS5 interface for reverse hostname lookup.
svn:r8451
Diffstat (limited to 'contrib/tor-resolve.py')
-rwxr-xr-x | contrib/tor-resolve.py | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/contrib/tor-resolve.py b/contrib/tor-resolve.py index dd44255bc1..3557c2aa96 100755 --- a/contrib/tor-resolve.py +++ b/contrib/tor-resolve.py @@ -32,15 +32,14 @@ def socks5Hello(): def socks5ParseHello(response): if response != "\x05\x00": raise ValueError("Bizarre socks5 response") -def socks5ResolveRequest(hostname): +def socks5ResolveRequest(hostname, atype=0x03, command=0xF0): version = 5 - command = 0xF0 rsv = 0 port = 0 - atype = 0x03 reqheader = struct.pack("!BBBBB",version, command, rsv, atype, len(hostname)) portstr = struct.pack("!H",port) return "%s%s%s"%(reqheader,hostname,portstr) + def socks5ParseResponse(r): if len(r)<8: return None @@ -49,18 +48,27 @@ def socks5ParseResponse(r): assert rsv==0 if reply != 0x00: return "ERROR",reply - assert atype in (0x01,0x04) - expected_len = 4 + ({1:4,4:16}[atype]) + 2 - if len(r) < expected_len: - return None - elif len(r) > expected_len: - raise ValueError("Overlong socks5 reply!") - addr = r[4:-2] - if atype == 0x01: - return "%d.%d.%d.%d"%tuple(map(ord,addr)) + assert atype in (0x01,0x03,0x04) + if atype != 0x03: + expected_len = 4 + ({1:4,4:16}[atype]) + 2 + if len(r) < expected_len: + return None + elif len(r) > expected_len: + raise ValueError("Overlong socks5 reply!") + addr = r[4:-2] + if atype == 0x01: + return "%d.%d.%d.%d"%tuple(map(ord,addr)) + else: + # not really the right way to format IPv6 + return "IPv6: %s"%(":".join([hex(ord(c)) for c in addr])) else: - # not really the right way to format IPv6 - return "IPv6: %s"%(":".join([hex(ord(c)) for c in addr])) + nul = r.index('\0',4) + return r[4:nul] + +def socks5ResolvePTRRequest(hostname): + return socks5ResolveRequest(socket.inet_aton(hostname), + atype=1, command = 0xF1) + def parseHostAndPort(h): host, port = "localhost", 9050 @@ -80,14 +88,18 @@ def parseHostAndPort(h): return host, port -def resolve(hostname, sockshost, socksport, socksver=4): +def resolve(hostname, sockshost, socksport, socksver=4, reverse=0): assert socksver in (4,5) if socksver == 4: fmt = socks4AResolveRequest parse = socks4AParseResponse - else: + elif not reverse: fmt = socks5ResolveRequest parse = socks5ParseResponse + else: + fmt = socks5ResolvePTRRequest + parse = socks5ParseResponse + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((sockshost,socksport)) if socksver == 5: @@ -114,14 +126,25 @@ if __name__ == '__main__': print "Syntax: resolve.py [-4|-5] hostname [sockshost:socksport]" sys.exit(0) socksver = 4 - if sys.argv[1] in ("-4", "-5"): - socksver = int(sys.argv[1][1]) - del sys.argv[1] - if len(sys.argv) == 4: + reverse = 0 + while sys.argv[1] == '-': + if sys.argv[1] in ("-4", "-5"): + socksver = int(sys.argv[1][1]) + del sys.argv[1] + elif sys.argv[1] == '-x': + reverse = 1 + del sys.argv[1] + elif sys.argv[1] == '--': + break + + if len(sys.argv) >= 4: print "Syntax: resolve.py [-4|-5] hostname [sockshost:socksport]" sys.exit(0) if len(sys.argv) == 3: sh,sp = parseHostAndPort(sys.argv[2]) else: sh,sp = parseHostAndPort("") - resolve(sys.argv[1], sh, sp, socksver) + + if reverse and socksver == 4: + socksver = 5 + resolve(sys.argv[1], sh, sp, socksver, reverse) |