def _run_trilateration(self, rounding_classes): """Runs a variance of the trilateration attack on the search_area Args: rouding_classes: a list of intervals with the radiuses Returns: A polygon in projected coordinates containing the target """ vb.vb_print(self.verbose, "Running trilateration", "UDP", True) # get minimum radius in the rounding classes MIN_R = sorted([cl[0] for cl in rounding_classes])[0][0] #initially the intersection is the whole area inter = self.search_area # place the attacker in the center if self.attacker.loc is None or self.attacker.loc[0] is None: starting_loc = cells.poly_centroid(inter, self.proj) self._place_at_coords(self.attacker, starting_loc[0], starting_loc[1], self.test_id) if self.oracle is None: self.oracle = apo.RoundingProximityOracle(self.auditor, rounding_classes, self.verbose) # initially get a rough estimate with 3 queries from # three locations at a distance of 120 degrees. # Initiate intersection rings rings = [] for i in range(3): # get a ring and check if we are switching to binary ring_response = self.__get_ring(MIN_R) if ring_response is None: raise SystemExit("victim not found") else: distance_range, ring = ring_response self._log_kml("ring", ring) rings.append(ring) #XXX no need to check for multipolygon in case of DUDP # as we are working inside a polygonal area inter_new = None if inter.geom_type == "MultiPolygon": for p in inter: cut_inter = p.intersection(ring) if inter_new is None: inter_new = cut_inter else: inter_new = inter_new.union(cut_inter) else: inter_new = inter.intersection(ring) # update the intersection inter = ring if inter_new.is_empty else inter_new # log kml files self.json_out["RUDP"].append({"query": self.attack_queries, "ring": self._log_kml("ring", ring), "active_area": self._log_kml("inter", inter), }) # update attacker location dist = float(distance_range[0] + distance_range[1]) / 2 # calculate new location for the next query new_loc = earth.point_on_earth(self.attacker.loc[0], self.attacker.loc[1], dist, i * 120) self._place_at_coords(self.attacker, new_loc[0], new_loc[1], self.test_id) # switch to binary return inter
def auditor_handled_place_at_dist(self, user, dist, bear, test_id, query_id=None): """Place a user of the auditing testsuite in a distance @dist km from their current location, at a bearing of @bearing, if it is allowed by the speed constraints. Notice that @auditor_user is not the user passed by the inherited class but an instance of the AuditorUser class used by the auditing framework Args: user: the user to be placed in a new location (AuditorUser instance) dist: distance further from the user's location in km bear: bearing in degrees test: the id of the test being run query: the query id for the current query Return Value: Returns a tuple (@result, @queries) where @result is True or False depending on whether the location was updated successfully or not. @queries is the total queries towards the service required to perform the update. Raises: AuditorException(with optional log data) in case an error occurs. """ # get the max distance the user is allowed to travel max_distance = self._get_max_distance(user) # If we have a speed limit and the distance is bigger than what # we are allowed to cross, sleep until we are allowed if dist > max_distance: sleep_time = (dist - max_distance) / self.speed_limit sleep(sleep_time + 1) # find new position at distance and angle new_pos = earth.point_on_earth(user.loc[0], user.loc[1], dist, bear) try: # given that the clocks won't change and we don't # run stuff in parallel, have time as primary key if query_id is None: query_id = int(time()) # if we have full logging create query record # create it here in case any exception is raised if self.logging == const.LOG.ALL: query_info = "auditor_set_location [" query_info += str(new_pos[0]) + "," + str(new_pos[1]) + "]" self._db.insert_query(query_id, test_id, user.user_id, user.service_id, query_info) set_loc_rspn = self.auditor_set_location(user.user, new_pos[0], new_pos[1]) if len(set_loc_rspn) != 2: raise SystemExit("auditor_set_location must return a tuple!") sleep(5) (result, queries) = set_loc_rspn if not isinstance(result, bool) and not isinstance(queries, int): error = "Wrong return type: Expecting (bool, int) or None" raise TypeError(error) # if no exception was raised but we failed log it if result is False and self.logging == const.LOG.ALL: self._db.log_query_fail(query_id) except AuditorException: if self.logging == const.LOG.ALL: self._db.log_query_fail(query_id) # handle any data that has been passed by the user self._db.exception_recovery(query_id) return (False, 1) except Exception as exception: # remove user from active users self.users.remove(user.user) self._db.log_query_fail(query_id) # else raise exception and record failure raise AuditorExceptionUnknown(str(exception), user.user_id) # update user info user.update_queries(queries) user.loc = new_pos return (result, queries)