def create(count): """Generate all types of descriptors and write them to files. :param integer count: How many sets of descriptors to generate, i.e. how many mock bridges/relays to create. """ logging.info("Generating %d bridge descriptors..." % int(count)) logging.info("Generated router nicknames:") server_descriptors = list() netstatus_consensus = list() extrainfo_descriptors = list() try: for i in xrange(int(count)): try: extrainfo, server, netstatus = generateDescriptors() except Exception as error: err, msg, tb = sys.exc_info() try: logging.error(error) except: print(traceback.print_tb(tb)) print(error) else: server_descriptors.append(server) netstatus_consensus.append(netstatus) extrainfo_descriptors.append(extrainfo) except KeyboardInterrupt as keyint: logging.warn("Received keyboard interrupt.") logging.warn("Stopping descriptor creation and exiting.") code = 1515 finally: logging.info("Writing descriptors to files...") cached = "cached-extrainfo.new" descriptor_files = { "networkstatus-bridges": ''.join(netstatus_consensus), "bridge-descriptors": ''.join(server_descriptors), "cached-extrainfo.new": ''.join(extrainfo_descriptors)} if not os.path.isfile(cached): with open(cached, 'wb') as fh: fh.flush() if os.path.isfile(cached): os.rename(cached, "cached-extrainfo") for fn, giantstring in descriptor_files.items(): util.writeDescToFile(fn, giantstring) logging.info("Done.") code = 0 sys.exit(code)
def createHiddenServiceDescriptors(count, replicas=2): """Generate hidden service descriptors. :param int count: How many sets of descriptors to generate. This essentially corresponds to the number of fake ``.onion`` s which should be mocked. :param int replicas: The number of times which one particular mocked Hidden Service should "replicate" its descriptor in the Tor Network's ``HSDir`` hashring. The default for real Hidden Services created with Tor is ``2``. """ logging.info("Generating %d hidden service descriptors..." % count) rendDescriptors = list() try: for i in range(int(count)): # Create replicas from [1, **replicas**], inclusive: for j in range(1, int(replicas)): desc = generateHSDesc(j) rendDescriptors.append(desc) except KeyboardInterrupt as keyint: logging.warn("Received keyboard interrupt.") logging.warn("Stopping descriptor creation and exiting.") code = 1515 except Exception as error: logging.exception(error) finally: logging.info("Writing descriptors to files...") descriptorFiles = { "rendezvous-service-descriptors": '\n'.join(rendDescriptors)} for fn, giantstring in descriptorFiles.items(): util.writeDescToFile(fn, giantstring) logging.info("Done.") code = 0 sys.exit(code)
def createRelayOrBridgeDescriptors(count, bridge=True, **kwargs): """Generate all types of descriptors and write them to files. :param int count: How many sets of descriptors to generate, i.e. how many mock bridges/relays to create. :param bool bridge: If ``True``, generate Bridge descriptors; otherwise, generate Relay descriptors. """ logging.info("Generating %d %s descriptors..." % (int(count), 'bridge' if bridge else 'relay')) logging.info("Generated router nicknames:") withoutTAP = False withoutNTOR = False if kwargs: if "withoutTAP" in kwargs: withoutTAP = kwargs.get("withoutTAP") if "withoutNTOR" in kwargs: withoutNTOR = kwargs.get("withoutNTOR") server_descriptors = list() netstatus_consensus = list() extrainfo_descriptors = list() try: # Add headers: netstatus_consensus.append( (b'flag-thresholds stable-uptime=613624 stable-mtbf=2488616 ' 'fast-speed=15000 guard-wfu=98.000% guard-tk=691200 ' 'guard-bw-inc-exits=55000 guard-bw-exc-exits=55000 enough-mtbf=1 ' 'ignoring-advertised-bws=0\n')) for i in xrange(int(count)): try: (extrainfo, server, netstatus) = generateDescriptors(bridge=bridge, withoutTAP=withoutTAP, withoutNTOR=withoutNTOR) except Exception as error: err, msg, tb = sys.exc_info() try: logging.debug(tb) logging.error(error) except: print(traceback.print_tb(tb)) print(error) else: server_descriptors.append(server) netstatus_consensus.append(netstatus) extrainfo_descriptors.append(extrainfo) except KeyboardInterrupt as keyint: logging.warn("Received keyboard interrupt.") logging.warn("Stopping descriptor creation and exiting.") code = 1515 finally: logging.info("Writing descriptors to files...") cached = "cached-extrainfo" cachedNew = "cached-extrainfo.new" # TODO: the `networkstatus-bridges` file and the `cached-consensus` # file should be sorted by fingerprint. if bridge: descriptorFiles = { "networkstatus-bridges": ''.join(netstatus_consensus), "bridge-descriptors": ''.join(server_descriptors)} else: # TODO: make the `cached-consensus` file have the appropriate # consensus headers. descriptorFiles = { "cached-consensus": ''.join(netstatus_consensus), "cached-descriptors": ''.join(server_descriptors)} # Both bridges and relay extrainfos are stored in the same filenames descriptorFiles[cachedNew] = ''.join(extrainfo_descriptors) if not os.path.isfile(cachedNew): with open(cachedNew, 'wb') as fh: fh.flush() if os.path.isfile(cachedNew): os.rename(cachedNew, cached) for fn, giantstring in descriptorFiles.items(): util.writeDescToFile(fn, giantstring) logging.info("Done.") code = 0 sys.exit(code)
def createRelayOrBridgeDescriptors(count, bridge=True, **kwargs): """Generate all types of descriptors and write them to files. :param int count: How many sets of descriptors to generate, i.e. how many mock bridges/relays to create. :param bool bridge: If ``True``, generate Bridge descriptors; otherwise, generate Relay descriptors. """ withoutTAP = False withoutNTOR = False numProbingVulnerable = 0 if kwargs: if "withoutTAP" in kwargs: withoutTAP = kwargs.get("withoutTAP") if "withoutNTOR" in kwargs: withoutNTOR = kwargs.get("withoutNTOR") if "numProbingVulnerable" in kwargs: numProbingVulnerable = kwargs.get("numProbingVulnerable") logging.info("Generating %d %s descriptors, among which %d only support " "protocols vulnerable to active probing..." % (int(count), 'bridge' if bridge else 'relay', numProbingVulnerable)) logging.info("Generated router nicknames:") server_descriptors = list() netstatus_consensus = list() extrainfo_descriptors = list() try: # Add headers: netstatus_consensus.append( (b'flag-thresholds stable-uptime=613624 stable-mtbf=2488616 ' 'fast-speed=15000 guard-wfu=98.000% guard-tk=691200 ' 'guard-bw-inc-exits=55000 guard-bw-exc-exits=55000 enough-mtbf=1 ' 'ignoring-advertised-bws=0\n')) for i in xrange(int(count)): try: pt_names = ['obfs2', 'obfs3', 'obfs4', 'scramblesuit'] # We facilitate the creation of descriptors that only advertise # transports that are vulnerable to active probing attacks. # This is necessary to keep BridgeDB's unit tests working after # our fix for bug 28655, in which we make active # probing-resistant bridges not give out transports that aren't # resistant to active probing: # <https://bugs.torproject.org/28655> if numProbingVulnerable: pt_names = ['obfs2', 'obfs3'] numProbingVulnerable -= 1 (extrainfo, server, netstatus) = generateDescriptors(bridge=pt_names, withoutTAP=withoutTAP, withoutNTOR=withoutNTOR) except Exception as error: err, msg, tb = sys.exc_info() try: logging.debug(tb) logging.error(error) except: print(traceback.print_tb(tb)) print(error) else: server_descriptors.append(server) netstatus_consensus.append(netstatus) extrainfo_descriptors.append(extrainfo) except KeyboardInterrupt as keyint: logging.warn("Received keyboard interrupt.") logging.warn("Stopping descriptor creation and exiting.") code = 1515 finally: logging.info("Writing descriptors to files...") cached = "cached-extrainfo" cachedNew = "cached-extrainfo.new" # TODO: the `networkstatus-bridges` file and the `cached-consensus` # file should be sorted by fingerprint. if bridge: descriptorFiles = { "networkstatus-bridges": ''.join(netstatus_consensus), "bridge-descriptors": ''.join(server_descriptors)} else: # TODO: make the `cached-consensus` file have the appropriate # consensus headers. descriptorFiles = { "cached-consensus": ''.join(netstatus_consensus), "cached-descriptors": ''.join(server_descriptors)} # Both bridges and relay extrainfos are stored in the same filenames descriptorFiles[cachedNew] = ''.join(extrainfo_descriptors) if not os.path.isfile(cachedNew): with open(cachedNew, 'wb') as fh: fh.flush() if os.path.isfile(cachedNew): os.rename(cachedNew, cached) for fn, giantstring in descriptorFiles.items(): util.writeDescToFile(fn, giantstring) logging.info("Done.") code = 0 sys.exit(code)