ExerciseServer.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. #!/usr/bin/python
  2. import TorControl
  3. import threading
  4. import socket
  5. import struct
  6. import random
  7. SOCKS_PORT=9050
  8. CONTROL_PORT=9051
  9. def runSocks4A(nonce, targetHost, targetPort, targetURL):
  10. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  11. s.connect(("127.0.0.1", SOCKS_PORT))
  12. socksheader = struct.pack("!BBHL", 4, 0x01, targetPort, 1)
  13. username = ""
  14. socksheader = "%s%s\x00%s\x00" %(socksheader, username, nonce)
  15. s.send(socksheader)
  16. response = s.recv(8)
  17. version,status,port=struct.unpack("!BBH",response[:4])
  18. if status != 90:
  19. print "Error: non-successful SOCKS status"
  20. s.close()
  21. return 0
  22. s.send("GET %s HTTP/1.0\r\nHost: %s\r\n\r\n"%(targetURL,targetHost))
  23. while 1:
  24. r = s.recv(1024)
  25. if not r:
  26. print "WOOT! Got a web page."
  27. s.close()
  28. return 1
  29. HOSTS_TO_TEST = [ "serifos", "chaoscomputerclub", "NetWorkXXIII", "caethaver2",
  30. "theoryorg", "samaire", "alrua", "ihopethisisunique",
  31. "xolotl", "cacophony", "ghettocluster", "torserverzillion",
  32. "ned", "richhomednsorg", "subzeronet"]
  33. EXITS_TO_TEST = [ "pvt", ]
  34. HOSTS_THAT_WORK = [ "serifos", "rodos", "moria2", "chaoscomputerclub"]
  35. EXITS_THAT_WORK = [ "serifos", "rodos"]
  36. TARGETS = [ ("belegost.mit.edu", "/"),
  37. ("seul.org", "/")]
  38. N_CIRCS_TO_TRY = 5*len(HOSTS_TO_TEST)
  39. CIRCS_AT_A_TIME = 3
  40. CIRC_LEN = 3
  41. HOST_STATUS = {}
  42. N_CIRCS_DONE = 0
  43. def launchCirc(s):
  44. htw = HOSTS_THAT_WORK[:]
  45. random.shuffle(htw)
  46. path = htw[:CIRC_LEN-2] + \
  47. [random.choice(HOSTS_TO_TEST)] + \
  48. [random.choice(EXITS_THAT_WORK)]
  49. circid = TorControl.extend_circuit(s, 0, path)
  50. for name in path:
  51. lst = HOST_STATUS.setdefault(name,[0,0])
  52. lst[0] += 1
  53. return circid, path
  54. def runControl(s):
  55. circs = {}
  56. s1,s2 = {},{}
  57. _h = lambda body,circs=circs,s1=s1,s2=s2,s=s:handleEvent(s,body,
  58. circs,s1,s2)
  59. TorControl._event_handler = _h
  60. TorControl.set_events(s,
  61. [TorControl.EVENT_TYPE.CIRCSTATUS,
  62. TorControl.EVENT_TYPE.STREAMSTATUS])
  63. TorControl.set_option(s,"__LeaveStreamsUnattached 1")
  64. global N_CIRCS_DONE
  65. while N_CIRCS_DONE < N_CIRCS_TO_TRY:
  66. while len(circs) < CIRCS_AT_A_TIME:
  67. c,p = launchCirc(s)
  68. print "launching circuit %s to %s"%(c,p)
  69. circs[c]=p
  70. _, tp, body = TorControl.receive_message(s)
  71. if tp == TorControl.MSG_TYPE.EVENT:
  72. handleEvent(s, body, circs, s1,s2)
  73. i = HOST_STATUS.items()
  74. i.sort()
  75. for n,(all,good) in i:
  76. print "%s in %s circuits; %s/%s ok"%(n,all,good,all)
  77. def handleEvent(s, body, circs, streamsByNonce, streamsByIdent):
  78. global N_CIRCS_DONE
  79. event, args = TorControl.unpack_event(body)
  80. if event == TorControl.EVENT_TYPE.STREAMSTATUS:
  81. status, ident, target = args
  82. print "Got stream event:",TorControl.STREAM_STATUS.nameOf[status],\
  83. ident,target
  84. if status in (TorControl.STREAM_STATUS.NEW_CONNECT,
  85. TorControl.STREAM_STATUS.NEW_RESOLVE,
  86. TorControl.STREAM_STATUS.DETACHED):
  87. target,port=target.split(":")
  88. if not target.endswith(".exnonce"):
  89. TorControl.attach_stream(s, ident, 0)
  90. else:
  91. circid, (host,url) = streamsByNonce[target]
  92. streamsByIdent[ident] = circid,(host,url)
  93. print "Redirecting circuit",circid,"to",host
  94. TorControl.redirect_stream(s, ident, host)
  95. TorControl.attach_stream(s, ident, circid)
  96. elif status in (TorControl.STREAM_STATUS.CLOSED,
  97. TorControl.STREAM_STATUS.FAILED):
  98. circid, (host,url) = streamsByIdent[ident]
  99. if circs.has_key(circid):
  100. for name in circs[circid]:
  101. HOST_STATUS[name][1] += 1
  102. del circs[circid]
  103. N_CIRCS_DONE += 1
  104. print N_CIRCS_DONE, "circuit attempts done"
  105. del streamsByIdent[ident]
  106. elif event == TorControl.EVENT_TYPE.CIRCSTATUS:
  107. status, ident, path = args
  108. print "Got circuit event",TorControl.CIRC_STATUS.nameOf[status],\
  109. ident,path
  110. if status in (TorControl.CIRC_STATUS.CLOSED,
  111. TorControl.CIRC_STATUS.FAILED):
  112. if circs.has_key(ident):
  113. print "Circuit failed."
  114. del circs[ident]
  115. N_CIRCS_DONE += 1
  116. print N_CIRCS_DONE, "circuit attempts done"
  117. elif status == TorControl.CIRC_STATUS.BUILT:
  118. nonce = random.randint(1,100000000)
  119. nonce = "%s.exnonce" % nonce
  120. host,url = random.choice(TARGETS)
  121. streamsByNonce[nonce] = ident, (host,url)
  122. print "Launching socks4a connection"
  123. t = threading.Thread(target=runSocks4A, args=(nonce, host, 80, url))
  124. t.setDaemon(1)
  125. t.start()
  126. def run():
  127. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  128. s.connect(("127.0.0.1", CONTROL_PORT))
  129. TorControl.authenticate(s)
  130. runControl(s)
  131. if __name__ == '__main__':
  132. run()