def runModule( moduleName, args, torCtrl ): logger.info("Running module '%s'." % moduleName) module = __import__("modules.%s" % moduleName, fromlist=[moduleName]) # Obtain the list of exit relays to scan. if args.exit: exitRelays = [args.exit] else: hosts = [(socket.gethostbyname(host), port) for (host, port) in module.destinations] exitRelays = exitselector.getExits(args.consensus, countryCode=args.country, hosts=hosts) count = len(exitRelays) if count < 1: raise error.ExitSelectionError("Exit selection yielded %d exits " \ "but need at least one." % count) handler = EventHandler(torCtrl, module.probe) torCtrl.add_event_listener(handler.newEvent, EventType.CIRC, EventType.STREAM) # Start building a circuit for every exit relay we got. logger.debug("Beginning to trigger %d circuit creations." % count) for exitRelay in exitRelays: try: torCtrl.new_circuit([const.FIRST_HOP, exitRelay]) except stem.ControllerError as err: logger.warning("Circuit with exit relay \"%s\" could not be " \ "created." % (exitRelay, err)) logger.debug("Done triggering circuit creations.")
def selectExits( args, module ): """ Based on the module's intended destinations, select exit relays to probe. Exit relays are selected for probing if their exit policy allows exiting to the module's intended destinations. """ before = datetime.datetime.now() hosts = [] # If no consensus was given over the command line, we take the one in the # data directory. if args.consensus: consensus = args.consensus else: consensus = const.TOR_DATA_DIRECTORY + "cached-consensus" if not os.path.exists(consensus): logger.error("The consensus \"%s\" does not exist." % consensus) exit(1) if module.destinations is not None: hosts = [(socket.gethostbyname(host), port) for (host, port) in module.destinations] # '-e' was used to specify a single exit relay. if args.exit: exitRelays = [args.exit] total = len(exitRelays) else: total, exitRelays = exitselector.getExits(consensus, countryCode=args.country, hosts=hosts) logger.debug("Successfully selected exit relays after %s." % str(datetime.datetime.now() - before)) logger.info("%d%s exits out of all %s exit relays allow exiting to %s." % (len(exitRelays), " %s" % args.country if args.country else "", total, hosts)) assert isinstance(exitRelays, list) random.shuffle(exitRelays) return exitRelays
def probe( moduleName, args, torCtrl ): logger.info("Running module '%s'." % moduleName) module = __import__("modules.%s" % moduleName, fromlist=[moduleName]) # Obtain the list of exit relays to scan. if args.exit: exitRelays = [args.exit] else: hosts = [(socket.gethostbyname(host), port) for (host, port) in module.targets] exitRelays = exitselector.getExits(args.consensus, countryCode=args.country, hosts=hosts) count = len(exitRelays) if count < 1: raise error.ExitSelectionError("Exit selection yielded %d exits " \ "but need at least one." % count) logger.info("About to probe %d exit relays." % count) # Create circuit pool and set up stream attacher. circuitPool = circuitpool.new(torCtrl, list(exitRelays)) eventHandler = streamattacher.new(circuitPool, torCtrl) torCtrl.add_event_listener(eventHandler.newEvent, EventType.STREAM) circuits = torCtrl.get_circuits() logger.debug("Open circuits:") for circuit in circuits: logger.debug(circuit) executor = ProcessPoolExecutor(max_workers=const.CIRCUIT_POOL_SIZE) logger.debug("Beginning to populate process pool with %d jobs." % count) # Invoke a module instance for every exit relay. for _ in xrange(count, 0, -1): cmd = command.new(None) executor.submit(module.probe, cmd, count) count -= 1 logger.info("Submitted jobs. Terminating main scanner.")