mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-30 15:43:32 +01:00
Remove the contrib scripts ExerciseServer.py, PathDemo.py,
and TorControl.py, as they use the old v0 controller protocol, and are obsoleted by TorFlow anyway. svn:r11464
This commit is contained in:
parent
ffce9d3368
commit
9966a11b4d
@ -21,6 +21,9 @@ Changes in version 0.2.0.7-alpha - 2007-??-??
|
||||
documents, and including it in router descriptors took up 60% (!) of
|
||||
compressed router descriptor downloads. Completes implementation of
|
||||
proposal 104.
|
||||
- Remove the contrib scripts ExerciseServer.py, PathDemo.py,
|
||||
and TorControl.py, as they use the old v0 controller protocol,
|
||||
and are obsoleted by TorFlow anyway.
|
||||
|
||||
o Major bugfixes:
|
||||
- Fix possible segfaults in functions called from
|
||||
|
@ -1,148 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import TorControl
|
||||
import threading
|
||||
import socket
|
||||
import struct
|
||||
import random
|
||||
|
||||
SOCKS_PORT=9050
|
||||
CONTROL_PORT=9051
|
||||
|
||||
def runSocks4A(nonce, targetHost, targetPort, targetURL):
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect(("127.0.0.1", SOCKS_PORT))
|
||||
socksheader = struct.pack("!BBHL", 4, 0x01, targetPort, 1)
|
||||
username = ""
|
||||
socksheader = "%s%s\x00%s\x00" %(socksheader, username, nonce)
|
||||
s.send(socksheader)
|
||||
response = s.recv(8)
|
||||
version,status,port=struct.unpack("!BBH",response[:4])
|
||||
if status != 90:
|
||||
print "Error: non-successful SOCKS status"
|
||||
s.close()
|
||||
return 0
|
||||
|
||||
s.send("GET %s HTTP/1.0\r\nHost: %s\r\n\r\n"%(targetURL,targetHost))
|
||||
while 1:
|
||||
r = s.recv(1024)
|
||||
if not r:
|
||||
print "WOOT! Got a web page."
|
||||
s.close()
|
||||
return 1
|
||||
|
||||
HOSTS_TO_TEST = [ "serifos", "chaoscomputerclub", "NetWorkXXIII", "caethaver2",
|
||||
"theoryorg", "samaire", "alrua", "ihopethisisunique",
|
||||
"xolotl", "cacophony", "ghettocluster", "torserverzillion",
|
||||
"ned", "richhomednsorg", "subzeronet"]
|
||||
EXITS_TO_TEST = [ "pvt", ]
|
||||
|
||||
HOSTS_THAT_WORK = [ "serifos", "rodos", "moria2", "chaoscomputerclub"]
|
||||
EXITS_THAT_WORK = [ "serifos", "rodos"]
|
||||
|
||||
TARGETS = [ ("belegost.mit.edu", "/"),
|
||||
("seul.org", "/")]
|
||||
|
||||
N_CIRCS_TO_TRY = 5*len(HOSTS_TO_TEST)
|
||||
CIRCS_AT_A_TIME = 3
|
||||
CIRC_LEN = 3
|
||||
|
||||
HOST_STATUS = {}
|
||||
N_CIRCS_DONE = 0
|
||||
def launchCirc(s):
|
||||
htw = HOSTS_THAT_WORK[:]
|
||||
random.shuffle(htw)
|
||||
path = htw[:CIRC_LEN-2] + \
|
||||
[random.choice(HOSTS_TO_TEST)] + \
|
||||
[random.choice(EXITS_THAT_WORK)]
|
||||
circid = TorControl.extend_circuit(s, 0, path)
|
||||
|
||||
for name in path:
|
||||
lst = HOST_STATUS.setdefault(name,[0,0])
|
||||
lst[0] += 1
|
||||
return circid, path
|
||||
|
||||
def runControl(s):
|
||||
circs = {}
|
||||
s1,s2 = {},{}
|
||||
_h = lambda body,circs=circs,s1=s1,s2=s2,s=s:handleEvent(s,body,
|
||||
circs,s1,s2)
|
||||
TorControl._event_handler = _h
|
||||
TorControl.set_events(s,
|
||||
[TorControl.EVENT_TYPE.CIRCSTATUS,
|
||||
TorControl.EVENT_TYPE.STREAMSTATUS])
|
||||
TorControl.set_option(s,"__LeaveStreamsUnattached 1")
|
||||
global N_CIRCS_DONE
|
||||
while N_CIRCS_DONE < N_CIRCS_TO_TRY:
|
||||
while len(circs) < CIRCS_AT_A_TIME:
|
||||
c,p = launchCirc(s)
|
||||
print "launching circuit %s to %s"%(c,p)
|
||||
circs[c]=p
|
||||
_, tp, body = TorControl.receive_message(s)
|
||||
if tp == TorControl.MSG_TYPE.EVENT:
|
||||
handleEvent(s, body, circs, s1,s2)
|
||||
i = HOST_STATUS.items()
|
||||
i.sort()
|
||||
for n,(all,good) in i:
|
||||
print "%s in %s circuits; %s/%s ok"%(n,all,good,all)
|
||||
|
||||
def handleEvent(s, body, circs, streamsByNonce, streamsByIdent):
|
||||
global N_CIRCS_DONE
|
||||
event, args = TorControl.unpack_event(body)
|
||||
if event == TorControl.EVENT_TYPE.STREAMSTATUS:
|
||||
status, ident, target = args
|
||||
print "Got stream event:",TorControl.STREAM_STATUS.nameOf[status],\
|
||||
ident,target
|
||||
if status in (TorControl.STREAM_STATUS.NEW_CONNECT,
|
||||
TorControl.STREAM_STATUS.NEW_RESOLVE,
|
||||
TorControl.STREAM_STATUS.DETACHED):
|
||||
target,port=target.split(":")
|
||||
if not target.endswith(".exnonce"):
|
||||
TorControl.attach_stream(s, ident, 0)
|
||||
else:
|
||||
circid, (host,url) = streamsByNonce[target]
|
||||
streamsByIdent[ident] = circid,(host,url)
|
||||
print "Redirecting circuit",circid,"to",host
|
||||
TorControl.redirect_stream(s, ident, host)
|
||||
TorControl.attach_stream(s, ident, circid)
|
||||
elif status in (TorControl.STREAM_STATUS.CLOSED,
|
||||
TorControl.STREAM_STATUS.FAILED):
|
||||
circid, (host,url) = streamsByIdent[ident]
|
||||
if circs.has_key(circid):
|
||||
for name in circs[circid]:
|
||||
HOST_STATUS[name][1] += 1
|
||||
del circs[circid]
|
||||
N_CIRCS_DONE += 1
|
||||
print N_CIRCS_DONE, "circuit attempts done"
|
||||
del streamsByIdent[ident]
|
||||
elif event == TorControl.EVENT_TYPE.CIRCSTATUS:
|
||||
status, ident, path = args
|
||||
print "Got circuit event",TorControl.CIRC_STATUS.nameOf[status],\
|
||||
ident,path
|
||||
if status in (TorControl.CIRC_STATUS.CLOSED,
|
||||
TorControl.CIRC_STATUS.FAILED):
|
||||
if circs.has_key(ident):
|
||||
print "Circuit failed."
|
||||
del circs[ident]
|
||||
N_CIRCS_DONE += 1
|
||||
print N_CIRCS_DONE, "circuit attempts done"
|
||||
elif status == TorControl.CIRC_STATUS.BUILT:
|
||||
nonce = random.randint(1,100000000)
|
||||
nonce = "%s.exnonce" % nonce
|
||||
host,url = random.choice(TARGETS)
|
||||
streamsByNonce[nonce] = ident, (host,url)
|
||||
print "Launching socks4a connection"
|
||||
t = threading.Thread(target=runSocks4A, args=(nonce, host, 80, url))
|
||||
t.setDaemon(1)
|
||||
t.start()
|
||||
|
||||
|
||||
def run():
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect(("127.0.0.1", CONTROL_PORT))
|
||||
TorControl.authenticate(s)
|
||||
runControl(s)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
||||
|
@ -1,99 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import TorControl
|
||||
import threading
|
||||
import socket
|
||||
import struct
|
||||
import random
|
||||
|
||||
circuits = {}
|
||||
streams = {}
|
||||
|
||||
def runControl(s):
|
||||
pendingEvents = [] #XXX This tric. should become standard
|
||||
TorControl._event_handler = pendingEvents.append
|
||||
TorControl.set_events(s,
|
||||
[TorControl.EVENT_TYPE.CIRCSTATUS,
|
||||
TorControl.EVENT_TYPE.STREAMSTATUS])
|
||||
TorControl.set_option(s,"__LeaveStreamsUnattached 1")
|
||||
while 1:
|
||||
e = pendingEvents[:]
|
||||
del pendingEvents[:]
|
||||
for ev in e:
|
||||
handleEvent(s, ev)
|
||||
_, tp, body = TorControl.receive_message(s)
|
||||
if tp == TorControl.MSG_TYPE.EVENT:
|
||||
handleEvent(s, body)
|
||||
|
||||
|
||||
def parsePath(name):
|
||||
assert name.endswith(".path")
|
||||
items = name.split(".")
|
||||
try:
|
||||
n = int(items[-2])
|
||||
except:
|
||||
return None,None
|
||||
path = items[-(2+n):-2]
|
||||
host = items[:-(2+n)]
|
||||
print path,host
|
||||
return path,".".join(host)
|
||||
|
||||
def handleEvent(s,body):
|
||||
event, args = TorControl.unpack_event(body)
|
||||
if event == TorControl.EVENT_TYPE.STREAMSTATUS:
|
||||
status, ident, target = args
|
||||
print "Got stream event:",TorControl.STREAM_STATUS.nameOf[status],\
|
||||
ident,target
|
||||
if status in (TorControl.STREAM_STATUS.NEW_CONNECT,
|
||||
TorControl.STREAM_STATUS.NEW_RESOLVE):
|
||||
target,port=target.split(":")
|
||||
if not target.endswith(".path"):
|
||||
TorControl.attach_stream(s, ident, 0)
|
||||
else:
|
||||
path,host = parsePath(target)
|
||||
#XXXX Don't launch so many circuits!
|
||||
streams[ident] = path,host
|
||||
circid = TorControl.extend_circuit(s, 0, path)
|
||||
circuits[circid] = path
|
||||
elif status == TorControl.STREAM_STATUS.DETACHED:
|
||||
if not streams.has_key(ident):
|
||||
TorControl.attach_stream(s, ident, 0)
|
||||
else:
|
||||
TorControl.close_stream(s, ident, 1)
|
||||
elif event == TorControl.EVENT_TYPE.CIRCSTATUS:
|
||||
status, ident, path = args
|
||||
print "Got circuit event",TorControl.CIRC_STATUS.nameOf[status],\
|
||||
ident,path
|
||||
if not circuits.has_key(ident):
|
||||
return
|
||||
if status in (TorControl.CIRC_STATUS.CLOSED,
|
||||
TorControl.CIRC_STATUS.FAILED):
|
||||
ok = 0
|
||||
elif status == TorControl.CIRC_STATUS.BUILT:
|
||||
ok = 1
|
||||
else:
|
||||
return
|
||||
|
||||
ids = [ streamID for (streamID, (path,host)) in streams.items()
|
||||
if path == circuits[ident] ]
|
||||
|
||||
for streamID in ids:
|
||||
if ok:
|
||||
_,host = streams[streamID]
|
||||
TorControl.redirect_stream(s, streamID, host)
|
||||
TorControl.attach_stream(s, streamID, ident)
|
||||
#XXXX Don't do this twice.
|
||||
else:
|
||||
TorControl.close_stream(s, streamID, 1)
|
||||
if not ok:
|
||||
del circuits[ident]
|
||||
|
||||
|
||||
def run():
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect(("127.0.0.1", 9051))
|
||||
TorControl.authenticate(s)
|
||||
runControl(s)
|
||||
|
||||
if __name__ == '__main__':
|
||||
run()
|
@ -1,464 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# TorControl.py -- Python module to interface with Tor Control interface.
|
||||
# Copyright 2005 Nick Mathewson -- See LICENSE for licensing information.
|
||||
#$Id$
|
||||
|
||||
# THIS MODULE IS OBSOLETE!
|
||||
#
|
||||
# There is a "TorCtl.py" module in the "control" directory in Tor CVS;
|
||||
# this new module supports the new ('version 1') Tor controller protocol
|
||||
# and has a far nicer and more object-oriented design than this module does.
|
||||
#
|
||||
# No further support will be done on this module.
|
||||
|
||||
import socket
|
||||
import struct
|
||||
import sys
|
||||
|
||||
#__all__ = [ "MSG_TYPE", "" ]
|
||||
|
||||
class _Enum:
|
||||
# Helper: define an ordered dense name-to-number 1-1 mapping.
|
||||
def __init__(self, start, names):
|
||||
self.nameOf = {}
|
||||
idx = start
|
||||
for name in names:
|
||||
setattr(self,name,idx)
|
||||
self.nameOf[idx] = name
|
||||
idx += 1
|
||||
class _Enum2:
|
||||
# Helper: define an ordered sparse name-to-number 1-1 mapping.
|
||||
def __init__(self, **args):
|
||||
self.__dict__.update(args)
|
||||
self.nameOf = {}
|
||||
for k,v in args.items():
|
||||
self.nameOf[v] = k
|
||||
|
||||
# Message types that client or server can send.
|
||||
MSG_TYPE = _Enum(0x0000,
|
||||
["ERROR",
|
||||
"DONE",
|
||||
"SETCONF",
|
||||
"GETCONF",
|
||||
"CONFVALUE",
|
||||
"SETEVENTS",
|
||||
"EVENT",
|
||||
"AUTH",
|
||||
"SAVECONF",
|
||||
"SIGNAL",
|
||||
"MAPADDRESS",
|
||||
"GETINFO",
|
||||
"INFOVALUE",
|
||||
"EXTENDCIRCUIT",
|
||||
"ATTACHSTREAM",
|
||||
"POSTDESCRIPTOR",
|
||||
"FRAGMENTHEADER",
|
||||
"FRAGMENT",
|
||||
"REDIRECTSTREAM",
|
||||
"CLOSESTREAM",
|
||||
"CLOSECIRCUIT",
|
||||
])
|
||||
|
||||
# Make sure that the enumeration code is working.
|
||||
assert MSG_TYPE.SAVECONF == 0x0008
|
||||
assert MSG_TYPE.CLOSECIRCUIT == 0x0014
|
||||
|
||||
# Types of "EVENT" message.
|
||||
EVENT_TYPE = _Enum(0x0001,
|
||||
["CIRCSTATUS",
|
||||
"STREAMSTATUS",
|
||||
"ORCONNSTATUS",
|
||||
"BANDWIDTH",
|
||||
"OBSOLETE_LOG",
|
||||
"NEWDESC",
|
||||
"DEBUG_MSG",
|
||||
"INFO_MSG",
|
||||
"NOTICE_MSG",
|
||||
"WARN_MSG",
|
||||
"ERR_MSG",
|
||||
])
|
||||
|
||||
assert EVENT_TYPE.ERR_MSG == 0x000B
|
||||
assert EVENT_TYPE.OBSOLETE_LOG == 0x0005
|
||||
|
||||
# Status codes for "CIRCSTATUS" events.
|
||||
CIRC_STATUS = _Enum(0x00,
|
||||
["LAUNCHED",
|
||||
"BUILT",
|
||||
"EXTENDED",
|
||||
"FAILED",
|
||||
"CLOSED"])
|
||||
|
||||
# Status codes for "STREAMSTATUS" events
|
||||
STREAM_STATUS = _Enum(0x00,
|
||||
["SENT_CONNECT",
|
||||
"SENT_RESOLVE",
|
||||
"SUCCEEDED",
|
||||
"FAILED",
|
||||
"CLOSED",
|
||||
"NEW_CONNECT",
|
||||
"NEW_RESOLVE",
|
||||
"DETACHED"])
|
||||
|
||||
# Status codes for "ORCONNSTATUS" events
|
||||
OR_CONN_STATUS = _Enum(0x00,
|
||||
["LAUNCHED","CONNECTED","FAILED","CLOSED"])
|
||||
|
||||
# Signal codes for "SIGNAL" events.
|
||||
SIGNAL = _Enum2(HUP=0x01,INT=0x02,USR1=0x0A,USR2=0x0C,TERM=0x0F)
|
||||
|
||||
# Error codes for "ERROR" events.
|
||||
ERR_CODES = {
|
||||
0x0000 : "Unspecified error",
|
||||
0x0001 : "Internal error",
|
||||
0x0002 : "Unrecognized message type",
|
||||
0x0003 : "Syntax error",
|
||||
0x0004 : "Unrecognized configuration key",
|
||||
0x0005 : "Invalid configuration value",
|
||||
0x0006 : "Unrecognized byte code",
|
||||
0x0007 : "Unauthorized",
|
||||
0x0008 : "Failed authentication attempt",
|
||||
0x0009 : "Resource exhausted",
|
||||
0x000A : "No such stream",
|
||||
0x000B : "No such circuit",
|
||||
0x000C : "No such OR"
|
||||
}
|
||||
|
||||
class TorCtlError(Exception):
|
||||
"Generic error raised by TorControl code."
|
||||
pass
|
||||
|
||||
class ProtocolError(TorCtlError):
|
||||
"Raised on violations in Tor controller protocol"
|
||||
pass
|
||||
|
||||
class ErrorReply(TorCtlError):
|
||||
""
|
||||
pass
|
||||
|
||||
def parseHostAndPort(h):
|
||||
host, port = "localhost", 9051
|
||||
if ":" in h:
|
||||
i = h.index(":")
|
||||
host = h[:i]
|
||||
try:
|
||||
port = int(h[i+1:])
|
||||
except ValueError:
|
||||
print "Bad hostname %r"%h
|
||||
sys.exit(1)
|
||||
elif h:
|
||||
try:
|
||||
port = int(h)
|
||||
except ValueError:
|
||||
host = h
|
||||
|
||||
return host, port
|
||||
|
||||
def _unpack_msg(msg):
|
||||
"return None, minLength, body or type,body,rest"
|
||||
if len(msg) < 4:
|
||||
return None, 4, msg
|
||||
length,type = struct.unpack("!HH",msg)
|
||||
if len(msg) >= 4+length:
|
||||
return type,msg[4:4+length],msg[4+length:]
|
||||
else:
|
||||
return None,4+length,msg
|
||||
|
||||
def _minLengthToPack(bytes):
|
||||
whole,left = divmod(bytes,65535)
|
||||
if left:
|
||||
return whole*(65535+4)+4+left
|
||||
else:
|
||||
return whole*(65535+4)
|
||||
|
||||
def unpack_msg(msg):
|
||||
"returns as for _unpack_msg"
|
||||
tp,body,rest = _unpack_msg(msg)
|
||||
if tp != MSG_TYPE.FRAGMENTHEADER:
|
||||
return tp, body, rest
|
||||
|
||||
if len(body) < 6:
|
||||
raise ProtocolError("FRAGMENTHEADER message too short")
|
||||
|
||||
realType,realLength = struct.unpack("!HL", body[:6])
|
||||
|
||||
# Okay; could the message _possibly_ be here?
|
||||
minLength = _minLengthToPack(realLength+6)
|
||||
if len(msg) < minLength:
|
||||
return None, minLength, msg
|
||||
|
||||
# Okay; optimistically try to build up the msg.
|
||||
soFar = [ body[6:] ]
|
||||
lenSoFarLen = len(body)-6
|
||||
while len(rest)>=4 and lenSoFar < realLength:
|
||||
ln, tp = struct.unpack("!HH", rest[:4])
|
||||
if tp != MSG_TYPE.FRAGMENT:
|
||||
raise ProtocolError("Missing FRAGMENT message")
|
||||
soFar.append(rest[4:4+ln])
|
||||
lenSoFar += ln
|
||||
if 4+ln > len(rest):
|
||||
rest = ""
|
||||
leftInPacket = 4+ln-len(rest)
|
||||
else:
|
||||
rest = rest[4+ln:]
|
||||
leftInPacket=0
|
||||
|
||||
if lenSoFar == realLength:
|
||||
return realType, "".join(soFar), rest
|
||||
elif lenSoFar > realLength:
|
||||
raise ProtocolError("Bad fragmentation: message longer than declared")
|
||||
else:
|
||||
inOtherPackets = realLength-lenSoFar-leftInPacket
|
||||
minLength = _minLengthToPack(inOtherPackets)
|
||||
return None, len(msg)+leftInPacket+inOtherPackets, msg
|
||||
|
||||
def _receive_msg(s):
|
||||
body = ""
|
||||
header = s.recv(4)
|
||||
length,type = struct.unpack("!HH",header)
|
||||
if length:
|
||||
while length > len(body):
|
||||
body += s.recv(length-len(body))
|
||||
return length,type,body
|
||||
|
||||
def receive_message(s):
|
||||
length, tp, body = _receive_msg(s)
|
||||
if tp != MSG_TYPE.FRAGMENTHEADER:
|
||||
return length, tp, body
|
||||
if length < 6:
|
||||
raise ProtocolError("FRAGMENTHEADER message too short")
|
||||
realType,realLength = struct.unpack("!HL", body[:6])
|
||||
data = [ body[6:] ]
|
||||
soFar = len(data[0])
|
||||
while 1:
|
||||
length, tp, body = _receive_msg(s)
|
||||
if tp != MSG_TYPE.FRAGMENT:
|
||||
raise ProtocolError("Missing FRAGMENT message")
|
||||
soFar += length
|
||||
data.append(body)
|
||||
if soFar == realLength:
|
||||
return realLength, realType, "".join(data)
|
||||
elif soFar > realLengtH:
|
||||
raise ProtocolError("FRAGMENT message too long!")
|
||||
|
||||
_event_handler = None
|
||||
def receive_reply(s, expected=None):
|
||||
while 1:
|
||||
_, tp, body = receive_message(s)
|
||||
if tp == MSG_TYPE.EVENT:
|
||||
if _event_handler is not None:
|
||||
_event_handler(body)
|
||||
elif tp == MSG_TYPE.ERROR:
|
||||
if len(body)<2:
|
||||
raise ProtocolError("(Truncated error message)")
|
||||
errCode, = struct.unpack("!H", body[:2])
|
||||
raise ErrorReply((errCode,
|
||||
ERR_CODES.get(errCode,"[unrecognized]"),
|
||||
body[2:]))
|
||||
elif (expected is not None) and (tp not in expected):
|
||||
raise ProtocolError("Unexpected message type 0x%04x"%tp)
|
||||
else:
|
||||
return tp, body
|
||||
|
||||
def pack_message(type, body=""):
|
||||
length = len(body)
|
||||
if length < 65536:
|
||||
reqheader = struct.pack("!HH", length, type)
|
||||
return "%s%s"%(reqheader,body)
|
||||
|
||||
fragheader = struct.pack("!HHHL",
|
||||
65535, MSG_TYPE.FRAGMENTHEADER, type, length)
|
||||
msgs = [ fragheader, body[:65535-6] ]
|
||||
body = body[65535-6:]
|
||||
while body:
|
||||
if len(body) > 65535:
|
||||
fl = 65535
|
||||
else:
|
||||
fl = len(body)
|
||||
fragheader = struct.pack("!HH", MSG_TYPE.FRAGMENT, fl)
|
||||
msgs.append(fragheader)
|
||||
msgs.append(body[:fl])
|
||||
body = body[fl:]
|
||||
|
||||
return "".join(msgs)
|
||||
|
||||
def send_message(s, type, body=""):
|
||||
s.sendall(pack_message(type, body))
|
||||
|
||||
def authenticate(s):
|
||||
send_message(s,MSG_TYPE.AUTH)
|
||||
type,body = receive_reply(s)
|
||||
return
|
||||
|
||||
def _parseKV(body,sep=" ",term="\n"):
|
||||
res = []
|
||||
for line in body.split(term):
|
||||
if not line: continue
|
||||
print repr(line)
|
||||
k, v = line.split(sep,1)
|
||||
res.append((k,v))
|
||||
return res
|
||||
|
||||
def get_option(s,name):
|
||||
send_message(s,MSG_TYPE.GETCONF,name)
|
||||
tp,body = receive_reply(s,[MSG_TYPE.CONFVALUE])
|
||||
return _parseKV(body)
|
||||
|
||||
def set_option(s,msg):
|
||||
send_message(s,MSG_TYPE.SETCONF,msg)
|
||||
tp,body = receive_reply(s,[MSG_TYPE.DONE])
|
||||
|
||||
def get_info(s,name):
|
||||
send_message(s,MSG_TYPE.GETINFO,name)
|
||||
tp,body = receive_reply(s,[MSG_TYPE.INFOVALUE])
|
||||
kvs = body.split("\0")
|
||||
d = {}
|
||||
for i in xrange(0,len(kvs)-1,2):
|
||||
d[kvs[i]] = kvs[i+1]
|
||||
return d
|
||||
|
||||
def set_events(s,events):
|
||||
send_message(s,MSG_TYPE.SETEVENTS,
|
||||
"".join([struct.pack("!H", event) for event in events]))
|
||||
type,body = receive_reply(s,[MSG_TYPE.DONE])
|
||||
return
|
||||
|
||||
def save_conf(s):
|
||||
send_message(s,MSG_TYPE.SAVECONF)
|
||||
receive_reply(s,[MSG_TYPE.DONE])
|
||||
|
||||
def send_signal(s, sig):
|
||||
send_message(s,MSG_TYPE.SIGNAL,struct.pack("B",sig))
|
||||
receive_reply(s,[MSG_TYPE.DONE])
|
||||
|
||||
def map_address(s, kv):
|
||||
msg = [ "%s %s\n"%(k,v) for k,v in kv ]
|
||||
send_message(s,MSG_TYPE.MAPADDRESS,"".join(msg))
|
||||
tp, body = receive_reply(s,[MSG_TYPE.DONE])
|
||||
return _parseKV(body)
|
||||
|
||||
def extend_circuit(s, circid, hops):
|
||||
msg = struct.pack("!L",circid) + ",".join(hops) + "\0"
|
||||
send_message(s,MSG_TYPE.EXTENDCIRCUIT,msg)
|
||||
tp, body = receive_reply(s,[MSG_TYPE.DONE])
|
||||
if len(body) != 4:
|
||||
raise ProtocolError("Extendcircuit reply too short or long")
|
||||
return struct.unpack("!L",body)[0]
|
||||
|
||||
def redirect_stream(s, streamid, newtarget):
|
||||
msg = struct.pack("!L",streamid) + newtarget + "\0"
|
||||
send_message(s,MSG_TYPE.REDIRECTSTREAM,msg)
|
||||
tp,body = receive_reply(s,[MSG_TYPE.DONE])
|
||||
|
||||
def attach_stream(s, streamid, circid):
|
||||
msg = struct.pack("!LL",streamid, circid)
|
||||
send_message(s,MSG_TYPE.ATTACHSTREAM,msg)
|
||||
tp,body = receive_reply(s,[MSG_TYPE.DONE])
|
||||
|
||||
def close_stream(s, streamid, reason=0, flags=0):
|
||||
msg = struct.pack("!LBB",streamid,reason,flags)
|
||||
send_message(s,MSG_TYPE.CLOSESTREAM,msg)
|
||||
tp,body = receive_reply(s,[MSG_TYPE.DONE])
|
||||
|
||||
def close_circuit(s, circid, flags=0):
|
||||
msg = struct.pack("!LB",circid,flags)
|
||||
send_message(s,MSG_TYPE.CLOSECIRCUIT,msg)
|
||||
tp,body = receive_reply(s,[MSG_TYPE.DONE])
|
||||
|
||||
def post_descriptor(s, descriptor):
|
||||
send_message(s,MSG_TYPE.POSTDESCRIPTOR,descriptor)
|
||||
tp,body = receive_reply(s,[MSG_TYPE.DONE])
|
||||
|
||||
def _unterminate(s):
|
||||
if s[-1] == '\0':
|
||||
return s[:-1]
|
||||
else:
|
||||
return s
|
||||
|
||||
def unpack_event(body):
|
||||
if len(body)<2:
|
||||
raise ProtocolError("EVENT body too short.")
|
||||
evtype, = struct.unpack("!H", body[:2])
|
||||
body = body[2:]
|
||||
if evtype == EVENT_TYPE.CIRCSTATUS:
|
||||
if len(body)<5:
|
||||
raise ProtocolError("CIRCUITSTATUS event too short.")
|
||||
status,ident = struct.unpack("!BL", body[:5])
|
||||
path = _unterminate(body[5:]).split(",")
|
||||
args = status, ident, path
|
||||
elif evtype == EVENT_TYPE.STREAMSTATUS:
|
||||
if len(body)<5:
|
||||
raise ProtocolError("CIRCUITSTATUS event too short.")
|
||||
status,ident = struct.unpack("!BL", body[:5])
|
||||
target = _unterminate(body[5:])
|
||||
args = status, ident, target
|
||||
elif evtype == EVENT_TYPE.ORCONNSTATUS:
|
||||
if len(body)<2:
|
||||
raise ProtocolError("CIRCUITSTATUS event too short.")
|
||||
status = ord(body[0])
|
||||
target = _unterminate(body[1:])
|
||||
args = status, target
|
||||
elif evtype == EVENT_TYPE.BANDWIDTH:
|
||||
if len(body)<8:
|
||||
raise ProtocolError("BANDWIDTH event too short.")
|
||||
read, written = struct.unpack("!LL",body[:8])
|
||||
args = read, written
|
||||
elif evtype == EVENT_TYPE.OBSOLETE_LOG:
|
||||
args = (_unterminate(body),)
|
||||
elif evtype == EVENT_TYPE.NEWDESC:
|
||||
args = (_unterminate(body).split(","),)
|
||||
elif EVENT_TYPE.DEBUG_MSG <= evtype <= EVENT_TYPE.ERR_MSG:
|
||||
args = (EVENT_TYPE.nameOf(evtype), _unterminate(body))
|
||||
else:
|
||||
args = (body,)
|
||||
|
||||
return evtype, args
|
||||
|
||||
def listen_for_events(s):
|
||||
while(1):
|
||||
_,type,body = receive_message(s)
|
||||
print unpack_event(body)
|
||||
return
|
||||
|
||||
def do_main_loop(host,port):
|
||||
print "host is %s:%d"%(host,port)
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((host,port))
|
||||
authenticate(s)
|
||||
print "nick",`get_option(s,"nickname")`
|
||||
print get_option(s,"DirFetchPeriod\n")
|
||||
print `get_info(s,"version")`
|
||||
#print `get_info(s,"desc/name/moria1")`
|
||||
print `get_info(s,"network-status")`
|
||||
print `get_info(s,"addr-mappings/all")`
|
||||
print `get_info(s,"addr-mappings/config")`
|
||||
print `get_info(s,"addr-mappings/cache")`
|
||||
print `get_info(s,"addr-mappings/control")`
|
||||
print `map_address(s, [("0.0.0.0", "Foobar.com"),
|
||||
("1.2.3.4", "foobaz.com"),
|
||||
("frebnitz.com", "5.6.7.8"),
|
||||
(".", "abacinator.onion")])`
|
||||
print `extend_circuit(s,0,["moria1"])`
|
||||
print '========'
|
||||
#print `extend_circuit(s,0,[""])`
|
||||
print '========'
|
||||
#send_signal(s,1)
|
||||
#save_conf(s)
|
||||
|
||||
#set_option(s,"1")
|
||||
#set_option(s,"bandwidthburstbytes 100000")
|
||||
#set_option(s,"runasdaemon 1")
|
||||
#set_events(s,[EVENT_TYPE.WARN])
|
||||
set_events(s,[EVENT_TYPE.OBSOLETE_LOG])
|
||||
|
||||
listen_for_events(s)
|
||||
|
||||
return
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 2:
|
||||
print "Syntax: TorControl.py torhost:torport"
|
||||
sys.exit(0)
|
||||
sh,sp = parseHostAndPort(sys.argv[1])
|
||||
do_main_loop(sh,sp)
|
||||
|
Loading…
Reference in New Issue
Block a user