def setup_complete(config, proto): print "setup complete:", proto print "Building a TorState" state = txtorcon.TorState(proto.tor_protocol) # Pass the config object yet again, avoiding global state state.post_bootstrap.addCallback(functools.partial(state_complete, config)) state.post_bootstrap.addErrback(setup_failed)
def main(connection): version = yield connection.get_info('version', 'events/names') print "Connected to Tor.", version['version'] print version['events/names'] print "Issuing NEWNYM." yield connection.signal('NEWNYM') print "OK." print "Building state." state = txtorcon.TorState(connection) yield state.post_bootstrap print "State initialized." print "Existing circuits:" for c in state.circuits.values(): print ' ', c print "listening for circuit events" state.add_circuit_listener(MyCircuitListener()) print "listening for INFO events" def print_info(i): print "INFO:", i connection.add_event_listener('INFO', print_info)
def list_circuits(options, proto): print("Circuits:") state = txtorcon.TorState(proto) yield state.post_bootstrap now = datetime.datetime.utcnow() util.dump_circuits(state, options['verbose'])
def delete_circuit(proto, circid, ifunused): # the already_deleted voodoo is because sometimes the circuit is # already marked as deleted before the OK comes back from the # controller, as in you get the event "first". # perhaps txtorcon should "fix"/normalize that such that it saves # events until the OK? maybe tor bug? class DetermineCircuitClosure(object): def __init__(self, target_id, done_deferred): self.circ_id = str(target_id) self.circuit_gone = False self.already_deleted = False self.completed = done_deferred def __call__(self, text): cid, what, _ = text.split(' ', 2) if what in ['CLOSED', 'FAILED']: if self.circ_id == cid: self.circuit_gone = True print("...circuit %s gone." % self.circ_id) sys.stdout.flush() if not self.already_deleted: self.completed.callback(self) unused_string = '(if unused) ' if ifunused else '' print('Deleting circuit %s"%s"...' % (unused_string, circid),) gone_d = defer.Deferred() monitor = DetermineCircuitClosure(circid, gone_d) proto.add_event_listener('CIRC', monitor) sys.stdout.flush() state = txtorcon.TorState(proto, bootstrap=False) kw = {} if ifunused: kw['IfUnused'] = True try: status = yield state.close_circuit(circid, **kw) monitor.already_deleted = True except txtorcon.TorProtocolError as e: gone_d.errback(e) yield gone_d return if monitor.circuit_gone: return print(status, '(waiting for CLOSED)...') sys.stdout.flush() yield gone_d
def build_circuit(proto, routers): state = txtorcon.TorState(proto) yield state.post_bootstrap if len(routers) == 1 and routers[0].lower() == 'auto': routers = None # print("Building new circuit, letting Tor select the path.") else: def find_router(args): position, name = args if name == '*': if position == 0: return random.choice(state.entry_guards.values()) else: return random.choice(state.routers.values()) r = state.routers.get(name) or state.routers.get('$'+name) if r is None: if len(name) == 40: print("Couldn't look up %s, but it looks like an ID" % name) r = name else: raise RuntimeError('Couldn\'t find router "%s".' % name) return r routers = map(find_router, enumerate(routers)) print("Building circuit:", '->'.join(map(util.nice_router_name, routers))) try: circ = yield state.build_circuit(routers) all_done = defer.Deferred() sys.stdout.write("Circuit ID %d: " % circ.id) sys.stdout.flush() state.add_circuit_listener(_BuiltCircuitListener(circ.id, all_done)) # all_done will callback when the circuit is built (or errback # if it fails). except txtorcon.TorProtocolError as e: log.err(e) yield all_done
def launch_and_get_protocol(ignore): d2 = txtorcon.launch_tor(config, reactor, stdout=sys.stdout) d2.addCallback( lambda tpp: txtorcon.TorState(tpp.tor_protocol).post_bootstrap) d2.addCallback(lambda state: state.protocol) return d2