def __init__(self, config_filepath): ''' Initialise the common data structures used by all PrivCount nodes. ''' self.config_filepath = normalise_path(config_filepath) self.config = None self.collection_delay = CollectionDelay()
def dump_state(self, state): ''' Dump the state dictionary to a saved state file. If state is none or an empty dictionary, do not write a file. ''' if state is None or len(state.keys()) == 0: return state_filepath = normalise_path(self.config['state']) with open(state_filepath, 'w') as fout: pickle.dump(state, fout)
def load_state(self): ''' Load the state from the saved state file Return the loaded state, or None if there is no state file ''' # load any state we may have from a previous run state_filepath = normalise_path(self.config['state']) if os.path.exists(state_filepath): with open(state_filepath, 'r') as fin: state = pickle.load(fin) return state return None
def load_match_list(file_path, check_domain=False, check_country=False, check_as=False, check_reason=False, check_onion=False): ''' Load a match list from file_path, checking the format based on check_*. Return a tuple with the normalised file path, and the match list. ''' file_path = normalise_path(file_path) assert os.path.exists(file_path) # import and validate this list of match names # This can take a few seconds match_list = [] with open(file_path, 'r') as fin: for line in fin: # Ignore leading or trailing whitespace line = line.strip() # Ignore comments if line_is_comment(line): continue try: if check_domain: assert check_domain_name(line) # Always lowercase matches, IANA likes them uppercase line = line.lower() line = line.strip(".") if check_country: assert check_country_code(line) # Always lowercase matches, MaxMind likes them uppercase line = line.lower() if check_as: # Now convert the AS number to an integer line = int(line) assert check_as_number(line) if check_reason: assert check_reason_str(line) # Always lowercase matches, don't depend on case matches line = line.lower() if check_onion: # Strip irrelevant URL and domain components, and lowercase line = strip_onion_str(line) # And then check: this makes checking easier to implement assert check_onion_string(line) except Exception as e: logging.warning("Line '{}' failed: {}".format(line, e)) raise e match_list.append(line) return (file_path, match_list)
def start_injecting(self): self.injecting = True if self.listeners is not None: logging.info("Injector has connected: no longer listening for new connections") stopListening(self.listeners) # This breaks the reference loop self.listeners = None if self.do_pause: logging.info("We will pause between the injection of each event to simulate actual event inter-arrival times, so this may take a while") if self.logpath == '-': self.event_file = sys.stdin else: self.event_file = open(normalise_path(self.logpath), 'r') self._inject_events()
def load_as_prefix_map(file_path): ''' Load an AS map from file_path. Never checks the format. Return a tuple with the normalised file path, and the AS map. ''' file_path = normalise_path(file_path) assert os.path.exists(file_path) map_list = [] with open(file_path, 'r') as fin: for line in fin: # Ignore leading or trailing whitespace line = line.strip() # Ignore comments if line_is_comment(line): continue map_list.append(line) return (file_path, map_list)
def refresh_config(self): ''' re-read config and process any changes ''' # TODO: refactor common code: see ticket #121 try: logging.debug("reading config file from '%s'", self.config_filepath) # read in the config from the given path with open(self.config_filepath, 'r') as fin: conf = yaml.load(fin) sk_conf = conf['share_keeper'] # find the path for the secret handshake file sk_conf['secret_handshake'] = choose_secret_handshake_path( sk_conf, conf) # if key path is not specified, use default path if 'key' in sk_conf: sk_conf['key'] = normalise_path(sk_conf['key']) else: sk_conf['key'] = normalise_path('privcount.rsa_key.pem') # if the key does not exist, generate a new key if not os.path.exists(sk_conf['key']): generate_keypair(sk_conf['key']) sk_conf['name'] = get_public_digest(sk_conf['key']) # the state file (unused) if 'state' in sk_conf: del sk_conf['state'] #sk_conf['state'] = normalise_path(sk_conf['state']) #assert os.path.exists(os.path.dirname(sk_conf['state'])) sk_conf['delay_period'] = self.get_valid_delay_period(sk_conf) sk_conf.setdefault('always_delay', False) assert isinstance(sk_conf['always_delay'], bool) sk_conf['sigma_decrease_tolerance'] = \ self.get_valid_sigma_decrease_tolerance(sk_conf) assert validate_connection_config(sk_conf['tally_server_info'], must_have_ip=True) if self.config == None: self.config = sk_conf logging.info("using config = %s", str(self.config)) else: changed = False for k in sk_conf: if k not in self.config or sk_conf[k] != self.config[k]: logging.info("updated config for key {} from {} to {}".format(k, self.config[k], sk_conf[k])) self.config[k] = sk_conf[k] changed = True if not changed: logging.debug('no config changes found') except AssertionError: logging.warning("problem reading config file: invalid data") log_error() except KeyError: logging.warning("problem reading config file: missing required keys") log_error()