Ejemplo n.º 1
0
def GetRawDevice(path):
    """Resolve the raw device that contains the path."""
    device_map = GetMountpoints()

    path = utils.SmartUnicode(path)
    mount_point = path = utils.NormalizePath(path, "/")

    result = rdf_paths.PathSpec(pathtype=rdf_paths.PathSpec.PathType.OS)

    # Assign the most specific mount point to the result
    while mount_point:
        try:
            result.path, fs_type = device_map[mount_point]
            if fs_type in SUPPORTED_FILESYSTEMS:
                # These are read filesystems
                result.pathtype = rdf_paths.PathSpec.PathType.OS
            else:
                logging.error(
                    "Filesystem %s is not supported. Supported filesystems "
                    "are %s", fs_type, SUPPORTED_FILESYSTEMS)
                result.pathtype = rdf_paths.PathSpec.PathType.UNSET

            # Drop the mount point
            path = utils.NormalizePath(path[len(mount_point):])
            result.mount_point = mount_point

            return result, path
        except KeyError:
            mount_point = os.path.dirname(mount_point)
Ejemplo n.º 2
0
def LinGetRawDevice(path):
    """Resolve the raw device that contains the path."""
    device_map = GetMountpoints()

    path = utils.SmartUnicode(path)
    mount_point = path = utils.NormalizePath(path, "/")

    result = rdf_paths.PathSpec(pathtype=rdf_paths.PathSpec.PathType.OS)

    # Assign the most specific mount point to the result
    while mount_point:
        try:
            result.path, fs_type = device_map[mount_point]
            if fs_type in ["ext2", "ext3", "ext4", "vfat", "ntfs"]:
                # These are read filesystems
                result.pathtype = rdf_paths.PathSpec.PathType.OS
            else:
                result.pathtype = rdf_paths.PathSpec.PathType.UNSET

            # Drop the mount point
            path = utils.NormalizePath(path[len(mount_point):])
            result.mount_point = mount_point

            return result, path
        except KeyError:
            mount_point = os.path.dirname(mount_point)
Ejemplo n.º 3
0
  def GenerateDirectory(self, input_dir=None, output_dir=None,
                        replacements=None):
    input_dir = utils.NormalizePath(input_dir)
    output_dir = utils.NormalizePath(output_dir)
    replacements = replacements or []

    for (root, _, files) in os.walk(input_dir):
      for filename in files:
        in_file = utils.JoinPath(root, filename)
        out_file = in_file.replace(input_dir, output_dir)
        for (s, replacement) in replacements:
          out_file = out_file.replace(s, replacement)
        self.EnsureDirExists(os.path.dirname(out_file))
        self.GenerateFile(in_file, out_file)
Ejemplo n.º 4
0
    def PopulateCache(self):
        """Parse the paths from the fixture."""
        if self.paths:
            return

        # The cache is attached to the class so it can be shared by all instance.
        self.paths = self.__class__.cache[self.prefix] = {}
        for path, (vfs_type, attributes) in client_fixture.VFS:
            if not path.startswith(self.prefix):
                continue

            path = utils.NormalizePath(path[len(self.prefix):])
            if path == "/":
                continue

            stat = rdf_client.StatEntry()
            args = {"client_id": "C.1234"}
            attrs = attributes.get("aff4:stat")

            if attrs:
                attrs %= args  # Remove any %% and interpolate client_id.
                stat = rdf_client.StatEntry.FromTextFormat(
                    utils.SmartStr(attrs))

            stat.pathspec = rdf_paths.PathSpec(
                pathtype=self.supported_pathtype, path=path)

            # TODO(user): Once we add tests around not crossing device boundaries,
            # we need to be smarter here, especially for the root entry.
            stat.st_dev = 1
            path = self._NormalizeCaseForPath(path, vfs_type)
            self.paths[path] = (vfs_type, stat)

        self.BuildIntermediateDirectories()
Ejemplo n.º 5
0
    def ParseFromString(self, initializer=None):
        """Create RDFRUN from string.

    Args:
      initializer: url string
    """
        # TODO(user): This is another ugly hack but we need to support legacy
        # clients that still send plain strings in their responses.
        if self.bare_string_re.match(initializer):
            initializer = "aff4:/" + initializer

        self._urn = urlparse.urlparse(initializer, scheme="aff4")

        # TODO(user): Another hack. Urlparse behaves differently in different
        # Python versions. We have to make sure the URL is not split at '?' chars.
        # At this point I think we should just give up on urlparse and roll our
        # own parsing...
        if self._urn.query:
            scheme = self._urn.scheme
            url = "%s?%s" % (self._urn.path, self._urn.query)
            netloc, params, query, fragment = "", "", "", ""
            self._urn = urlparse.ParseResult(scheme, netloc, url, params,
                                             query, fragment)

        # Normalize the URN path component
        # namedtuple _replace() is not really private.
        # pylint: disable=protected-access
        self._urn = self._urn._replace(
            path=utils.NormalizePath(self._urn.path))
        if not self._urn.scheme:
            self._urn = self._urn._replace(scheme="aff4")

        self._string_urn = self._urn.geturl()
Ejemplo n.º 6
0
  def testTSKFileCasing(self):
    """Test our ability to read the correct casing from image."""
    path = os.path.join(self.base_path, "test_img.dd")
    path2 = os.path.join("test directory", "NuMbErS.TxT")

    ps2 = rdfvalue.PathSpec(
        path=path2,
        pathtype=rdfvalue.PathSpec.PathType.TSK)

    ps = rdfvalue.PathSpec(path=path,
                           pathtype=rdfvalue.PathSpec.PathType.OS)
    ps.Append(ps2)
    fd = vfs.VFSOpen(ps)

    # This fixes Windows paths.
    path = path.replace("\\", "/")
    # The pathspec should have 2 components.

    self.assertEqual(fd.pathspec.first.path,
                     utils.NormalizePath(path))
    self.assertEqual(fd.pathspec.first.pathtype,
                     rdfvalue.PathSpec.PathType.OS)

    nested = fd.pathspec.last
    self.assertEqual(nested.path, u"/Test Directory/numbers.txt")
    self.assertEqual(nested.pathtype, rdfvalue.PathSpec.PathType.TSK)
Ejemplo n.º 7
0
    def Run(self, args):
        """Delete all the GRR temp files in path.

    If path is a directory, look in the top level for filenames beginning with
    Client.tempfile_prefix, and delete them.

    If path is a regular file and starts with Client.tempfile_prefix delete it.

    Args:
      args: pathspec pointing to directory containing temp files to be
            deleted, or a single file to be deleted.
    Returns:
      deleted: array of filename strings that were deleted
    Raises:
      ErrorBadPath: if path doesn't exist or is not a regular file or directory
    """

        # Normalize the path, so DeleteGRRTempFile can correctly check if
        # it is within Client.tempdir.
        if args.path:
            path = client_utils.CanonicalPathToLocalPath(
                utils.NormalizePath(args.path))
        else:
            path = config_lib.CONFIG["Client.tempdir"]

        deleted = []
        errors = []
        if os.path.isdir(path):
            for filename in os.listdir(path):
                abs_filename = os.path.join(path, filename)

                try:
                    DeleteGRRTempFile(abs_filename)
                    deleted.append(abs_filename)
                except Exception as e:  # pylint: disable=broad-except
                    # The error we are most likely to get is ErrorNotTempFile but
                    # especially on Windows there might be locking issues that raise
                    # various WindowsErrors so we just catch them all and continue
                    # deleting all other temp files in this directory.
                    errors.append(e)

        elif os.path.isfile(path):
            DeleteGRRTempFile(path)
            deleted = [path]

        elif not os.path.exists(path):
            raise ErrorBadPath("File %s does not exist" % path)
        else:
            raise ErrorBadPath("Not a regular file or directory: %s" % path)

        reply = ""
        if deleted:
            reply = "Deleted: %s." % deleted
        else:
            reply = "Nothing deleted."
        if errors:
            reply += "\n%s" % errors

        self.SendReply(rdf_client.LogMessage(data=reply))
Ejemplo n.º 8
0
    def Interpolate(self, client=None):
        for pattern in self.InterpolateClientAttributes(client=client):
            # Normalize the component path (this allows us to resolve ../
            # sequences).
            pattern = utils.NormalizePath(pattern.replace("\\", "/"))

            for pattern in self.InterpolateGrouping(pattern):
                yield pattern
Ejemplo n.º 9
0
    def ParseFromString(self, initializer):
        """Create RDFRUN from string.

    Args:
      initializer: url string
    """
        # Strip off the aff4: prefix if necessary.
        if initializer.startswith("aff4:/"):
            initializer = initializer[5:]

        self._string_urn = utils.NormalizePath(initializer)
Ejemplo n.º 10
0
Archivo: paths.py Proyecto: binsrc/grr
    def Interpolate(self, client=None):
        kb = client.Get(client.Schema.KNOWLEDGE_BASE)
        patterns = artifact_utils.InterpolateKbAttributes(self._value, kb)

        for pattern in patterns:
            # Normalize the component path (this allows us to resolve ../
            # sequences).
            pattern = utils.NormalizePath(pattern.replace("\\", "/"))

            for pattern in self.InterpolateGrouping(pattern):
                yield pattern
Ejemplo n.º 11
0
    def testNormpath(self):
        """Test our Normpath."""
        data = [
            ("foo/../../../../", "/"),
            ("/foo/../../../../bar", "/bar"),
            ("/foo/bar/../3sdfdfsa/.", "/foo/3sdfdfsa"),
            ("../foo/bar", "/foo/bar"),
            ("./foo/bar", "/foo/bar"),
            ("/", "/"),
        ]

        for test, expected in data:
            self.assertEqual(expected, utils.NormalizePath(test))
Ejemplo n.º 12
0
  def Run(self, args):
    """Delete all the GRR temp files in path.

    If path is a directory, look in the top level for filenames beginning with
    Client.tempfile_prefix, and delete them.

    If path is a regular file and starts with Client.tempfile_prefix delete it.

    Args:
      args: pathspec pointing to directory containing temp files to be
            deleted, or a single file to be deleted.
    Returns:
      deleted: array of filename strings that were deleted
    Raises:
      ErrorBadPath: if path doesn't exist or is not a regular file or directory
    """

    # Normalize the path, so DeleteGRRTempFile can correctly check if
    # it is within Client.tempdir.
    if args.path:
      path = client_utils.CanonicalPathToLocalPath(
          utils.NormalizePath(args.path))
    else:
      path = config_lib.CONFIG["Client.tempdir"]

    deleted = []
    if os.path.isdir(path):
      for filename in os.listdir(path):
        abs_filename = os.path.join(path, filename)

        try:
          DeleteGRRTempFile(abs_filename)
          deleted.append(abs_filename)
        except ErrorNotTempFile:
          pass

    elif os.path.isfile(path):
      DeleteGRRTempFile(path)
      deleted = [path]

    elif not os.path.exists(path):
      raise ErrorBadPath("File %s does not exist" % path)
    else:
      raise ErrorBadPath("Not a regular file or directory: %s" % path)

    out_rdfvalue = rdfvalue.LogMessage(data="Deleted: %s" % deleted)
    self.SendReply(out_rdfvalue)
Ejemplo n.º 13
0
def GetRawDevice(path):
    """Resolves the raw device that contains the path.

  Args:
    path: A path to examine.

  Returns:
    A pathspec to read the raw device as well as the modified path to read
    within the raw device. This is usually the path without the mount point.

  Raises:
    IOError: if the path does not exist or some unexpected behaviour occurs.
  """
    path = CanonicalPathToLocalPath(path)
    # Try to expand the shortened paths
    try:
        path = win32file.GetLongPathName(path)
    except pywintypes.error:
        pass

    try:
        mount_point = win32file.GetVolumePathName(path)
    except pywintypes.error as details:
        logging.info("path not found. %s", details)
        raise IOError("No mountpoint for path: %s", path)

    if not path.startswith(mount_point):
        stripped_mp = mount_point.rstrip("\\")
        if not path.startswith(stripped_mp):
            raise IOError("path %s is not mounted under %s" %
                          (path, mount_point))

    corrected_path = LocalPathToCanonicalPath(path[len(mount_point):])
    corrected_path = utils.NormalizePath(corrected_path)

    volume = win32file.GetVolumeNameForVolumeMountPoint(mount_point).rstrip(
        "\\")
    volume = LocalPathToCanonicalPath(volume)

    # The pathspec for the raw volume
    result = rdf_paths.PathSpec(path=volume,
                                pathtype=rdf_paths.PathSpec.PathType.OS,
                                mount_point=mount_point.rstrip("\\"))

    return result, corrected_path
Ejemplo n.º 14
0
def CanonicalPathToLocalPath(path):
    """Linux uses a normal path.

  We always want to encode as UTF-8 here. If the environment for the
  client is broken, Python might assume an ASCII based filesystem
  (those should be rare nowadays) and things will go wrong if we let
  Python decide what to do. If the filesystem actually is ASCII,
  encoding and decoding will not change anything so things will still
  work as expected.

  Args:
    path: the canonical path as an Unicode string

  Returns:
    a unicode string or an encoded (narrow) string dependent on
    system settings

  """
    return utils.SmartStr(utils.NormalizePath(path))
Ejemplo n.º 15
0
    def testTSKFileInode(self):
        """Test opening a file through an indirect pathspec."""
        pathspec = rdf_paths.PathSpec(path=os.path.join(
            self.base_path, "test_img.dd"),
                                      pathtype=rdf_paths.PathSpec.PathType.OS)
        pathspec.Append(pathtype=rdf_paths.PathSpec.PathType.TSK,
                        inode=12,
                        path="/Test Directory")
        pathspec.Append(pathtype=rdf_paths.PathSpec.PathType.TSK,
                        path="numbers.txt")

        fd = vfs.VFSOpen(pathspec)

        # Check that the new pathspec is correctly reduced to two components.
        self.assertEqual(
            fd.pathspec.first.path,
            utils.NormalizePath(os.path.join(self.base_path, "test_img.dd")))
        self.assertEqual(fd.pathspec[1].path, "/Test Directory/numbers.txt")

        # And the correct inode is placed in the final branch.
        self.assertEqual(fd.Stat().pathspec.nested_path.inode, 15)
        self.TestFileHandling(fd)
Ejemplo n.º 16
0
def CanonicalPathToLocalPath(path):
  """Linux uses a normal path.

  If sys.getfilesystemencoding() returns None normally any call to
  a system function will try to encode the string to ASCII.
  A modern version of Linux will use UTF-8 as (narrow) string encoding.
  locale.getpreferredencoding() seems to return ASCII at this point.
  So for older versions of Linux we'll need to rely on
  locale.getdefaultlocale()[1]. If everything fails we fallback to UTF-8.

  Args:
    path: the canonical path as an Unicode string

  Returns:
    a unicode string or an encoded (narrow) string dependent on
    system settings
  """
  canonical_path = utils.NormalizePath(path)

  if sys.getfilesystemencoding():
    return canonical_path

  encoding = locale.getdefaultlocale()[1] or "UTF-8"
  return canonical_path.encode(encoding)
Ejemplo n.º 17
0
    def Interpolate(self, client=None):
        try:
            kb = client.Get(client.Schema.KNOWLEDGE_BASE)
            if not kb:
                raise artifact_lib.KnowledgeBaseInterpolationError(
                    "Client has no knowledge base")

            patterns = artifact_lib.InterpolateKbAttributes(self._value, kb)
        except artifact_lib.KnowledgeBaseInterpolationError:
            # TODO(user): Deprecate InterpolateClientAttributes() support and
            # make KnowledgeBase the default and only option as soon as we're
            # confident that it's fully populated.
            logging.debug(
                "Can't interpolate glob %s with knowledge base attributes, "
                "reverting to client attributes.", utils.SmartUnicode(self))
            patterns = self.InterpolateClientAttributes(client=client)

        for pattern in patterns:
            # Normalize the component path (this allows us to resolve ../
            # sequences).
            pattern = utils.NormalizePath(pattern.replace("\\", "/"))

            for pattern in self.InterpolateGrouping(pattern):
                yield pattern
Ejemplo n.º 18
0
def LocalPathToCanonicalPath(path):
    """Linux uses a normal path."""
    return utils.NormalizePath(path)