def fingerprint(self): """Select num_probes most useful paths, and fetch them from the site at url. Return an ordered list of possible versions or []. """ self._load_db() paths = wafu.pick_fingerprint_files(self.path_nodes, self.all_versions) self.logger.logStartFingerprint(self.url, self.app_name) self.error_page_fingerprint = wafu.identify_error_page(self.url) possible_vers = [] for path in paths[:self.num_probes]: curr_vers = self.fingerprint_file(path) if curr_vers: possible_vers.append(curr_vers) if self._host_down_errors >= HOST_DOWN_THRESHOLD: break ver_set = wafu.collapse_version_possibilities(possible_vers) self.ver_list = list(ver_set) #if more than one possibility, try to narrow it by winnowing! if len(self.ver_list) > 1 and self.winnow: print "ver_list before winnowing:" for v in self.ver_list: print v.vstring print "\n" self.winnow_versions(possible_vers) ver_set = wafu.collapse_version_possibilities(possible_vers) self.ver_list = list(ver_set) self.ver_list.sort() if len(self.ver_list) > 1: self.best_guess = wafu.pick_likely_version(self.ver_list) elif len(self.ver_list) == 1: self.best_guess = self.ver_list[0] else: self.best_guess = None self.logger.logFinishFingerprint(self.ver_list, self.best_guess) return self.ver_list
def winnow_versions(self, possible_vers): winnow_attempts = 0 while len(self.ver_list) > 1 and winnow_attempts < self.num_probes: winnow_paths = wafu.pick_winnow_files(self.ver_list, self.version_nodes, self.num_probes - winnow_attempts) if not winnow_paths: break for path in winnow_paths: winnow_attempts += 1 curr_vers = self.fingerprint_file(path) if curr_vers: possible_vers.append(curr_vers) tmp_ver_set = wafu.collapse_version_possibilities(possible_vers) #if winnowing knocked out a possibility, repick winnow files base on this new info if len(tmp_ver_set) < len(self.ver_list): self.ver_list = list(tmp_ver_set) print "winnow eliminated a version... repicking" continue if self._host_down_errors >= HOST_DOWN_THRESHOLD: break if winnow_attempts > self.num_probes: break