예제 #1
0
  def RenderBranch(self, path, request):
    """Renders tree leafs for filesystem path."""
    aff4_root = rdfvalue.RDFURN(request.REQ.get("aff4_root", aff4.ROOT_URN))
    container = request.REQ.get("container")
    if not container:
      raise RuntimeError("Container not provided.")

    # Path is relative to the aff4 root specified.
    urn = aff4_root.Add(path)

    # Open the container
    container = aff4.FACTORY.Open(container, token=request.token)
    # Find only direct children of this tree branch.

    # NOTE: Although all AFF4Volumes are also containers, this gui element is
    # really only suitable for showing AFF4Collection objects which are not very
    # large, since we essentially list all members.
    query_expression = ("subject matches '%s.+'" % utils.EscapeRegex(urn))

    branches = set()

    for child in container.Query(query_expression):
      try:
        branch, _ = child.urn.RelativeName(urn).split("/", 1)
        branches.add(branch)
      except ValueError:
        pass

    # This actually sorts by the URN (which is UTF8) - I am not sure about the
    # correct sorting order for unicode string?
    directory_like = list(branches)
    directory_like.sort(cmp=locale.strcoll)

    for d in directory_like:
      self.AddElement(d)
예제 #2
0
  def Resolve(self, subject, predicate, token=None):
    """Retrieve a value set for a subject's predicate.

    This method is easy to use but always gets the latest version of the
    attribute. It is more flexible and efficient to use the other Resolve
    methods.

    Args:
      subject: The subject URN.
      predicate: The predicate URN.
      token: An ACL token.

    Returns:
      A (value, timestamp in microseconds) stored in the datastore cell, or
      (None, 0) or a (decoded protobuf, timestamp) if protobuf was
      specified. Value will be the same type as originally stored with Set().

    Raises:
      AccessError: if anything goes wrong.
    """
    for _, value, timestamp in self.ResolveMulti(
        subject, [utils.EscapeRegex(predicate)],
        token=token, timestamp=self.NEWEST_TIMESTAMP):

      # Just return the first one.
      return value, timestamp

    return (None, 0)
예제 #3
0
파일: rdfvalue.py 프로젝트: zzzzpaul/grr
 def Startswith(attribute, filter_implemention, string):
     return filter_implemention.PredicateContainsFilter(
         attribute, "^" + utils.EscapeRegex(string))
예제 #4
0
파일: rdfvalue.py 프로젝트: zzzzpaul/grr
 def Startswith(unused_attribute, filter_implemention, string):
     return filter_implemention.SubjectContainsFilter(
         "^" + utils.EscapeRegex(string))
예제 #5
0
  def BuildTable(self, start_row, end_row, request):
    """Populate the table."""
    # Default sort direction
    sort = request.REQ.get("sort", "Name:asc")
    try:
      reverse_sort = sort.split(":")[1] == "desc"
    except IndexError:
      reverse_sort = False

    filter_term = request.REQ.get("filter")
    aff4_path = request.REQ.get("aff4_path", self.root_path)
    urn = rdfvalue.RDFURN(aff4_path)

    filter_string = None
    if filter_term:
      column, regex = filter_term.split(":", 1)

      escaped_regex = utils.EscapeRegex(aff4_path + "/")
      # The start anchor refers only to this directory.
      if regex.startswith("^"):
        escaped_regex += utils.EscapeRegex(regex[1:])
      else:
        escaped_regex += ".*" + utils.EscapeRegex(regex)

      filter_string = "subject matches '%s'" % escaped_regex

    # For now we just list the directory
    try:
      key = utils.SmartUnicode(urn)
      if filter_string:
        key += ":" + filter_string

      # Open the directory as a directory.
      directory_node = aff4.FACTORY.Open(urn, token=request.token).Upgrade(
          "VFSDirectory")
      if not directory_node:
        raise IOError()

      key += str(directory_node.Get(directory_node.Schema.LAST))
      key += ":" + str(request.token)
      try:
        children = self.content_cache.Get(key)
      except KeyError:
        # Only show the direct children.
        children = sorted(directory_node.Query(filter_string=filter_string,
                                               limit=100000))

        # Filter the children according to types.
        if self.visible_types:
          children = [x for x in children
                      if x.__class__.__name__ in self.visible_types]

        self.content_cache.Put(key, children)

        try:
          self.message = "Directory Listing '%s' was taken on %s" % (
              aff4_path, directory_node.Get(directory_node.Schema.TYPE.age))
        except AttributeError:
          pass

    except IOError:
      children = []

    children.sort(reverse=reverse_sort)
    row_index = start_row

    # Make sure the table knows how large it is for paging.
    self.size = len(children)
    self.columns[1].base_path = urn
    for fd in children[start_row:end_row]:
      # We use the timestamp on the TYPE as a proxy for the last update time
      # of this object - its only an estimate.
      fd_type = fd.Get(fd.Schema.TYPE)
      if fd_type:
        self.AddCell(row_index, "Age", rdfvalue.RDFDatetime(fd_type.age))

      self.AddCell(row_index, "Name", fd.urn)

      # Add the fd to all the columns
      for column in self.columns:
        # This sets AttributeColumns directly from their fd.
        if isinstance(column, semantic.AttributeColumn):
          column.AddRowFromFd(row_index, fd)

      if "Container" in fd.behaviours:
        self.AddCell(row_index, "Icon", dict(icon="directory",
                                             description="Directory"))
      else:
        self.AddCell(row_index, "Icon", dict(icon="file",
                                             description="File Like Object"))

      row_index += 1
      if row_index > end_row:
        return
예제 #6
0
    def Query(self,
              attributes=None,
              filter_obj=None,
              subject_prefix="",
              token=None,
              subjects=None,
              limit=100,
              timestamp=None):
        """Selects a set of subjects based on filters."""
        if filter_obj:
            spec = filter_obj.FilterExpression()
        else:
            spec = {}

        try:
            skip, limit = limit
        except TypeError:
            skip = 0

        if attributes is None: attributes = []

        if u"aff4:type" not in attributes:
            attributes.append(u"aff4:type")

        # Make this lookup fast
        if subjects:
            subjects = set(subjects)
        attributes = [EscapeKey(x) for x in attributes]

        result_subjects = []

        if subject_prefix:
            regex = utils.EscapeRegex(EscapeKey(subject_prefix))
            spec = {"$and": [spec, {"_id": {"$regex": "^" + regex}}]}

        if subjects:
            expressions = []
            for subject in subjects:
                regex = utils.EscapeRegex(EscapeKey(subject))
                expressions.append({"_id": {"$regex": "^" + regex + "$"}})

            spec = {"$and": [spec, {"$or": expressions}]}

        for document in self.collection.find(spec=spec,
                                             fields=attributes,
                                             skip=skip,
                                             limit=limit,
                                             slave_okay=True):
            try:
                subject = DecodeKey(document["_id"])
                # Only yield those subjects which we are allowed to view.
                self.security_manager.CheckDataStoreAccess(
                    token, [subject], "r")

                result = dict(subject=[(subject, 0)])
                for key, values in document.items():
                    if isinstance(values, list):
                        if timestamp:
                            if timestamp == self.ALL_TIMESTAMPS:
                                pass
                            elif timestamp == self.NEWEST_TIMESTAMP:
                                values.sort(key=lambda t: t["t"])
                                values = values[-1:]
                            else:
                                try:
                                    ts_start, ts_end = timestamp
                                    values = [
                                        v for v in values
                                        if ts_start <= v["t"] <= ts_end
                                    ]
                                except (ValueError, TypeError):
                                    raise RuntimeError(
                                        "Invalid timestamp value: %s" %
                                        utils.SmartStr(timestamp))
                        for v in values:
                            result.setdefault(key, []).append(
                                (Decode(v["v"]), v["t"]))

                result_subjects.append(result)
            except access_control.UnauthorizedAccess:
                pass

        result_subjects.sort()
        total_count = len(result_subjects)
        result_set = data_store.ResultSet(result_subjects)
        result_set.total_count = total_count
        return result_set