Example #1
0
    def FingerprintFile(self, pathspec, max_filesize=None, request_data=None):
        """Launch a fingerprint client action."""
        request = rdf_client_action.FingerprintRequest(pathspec=pathspec)
        if max_filesize is not None:
            request.max_filesize = max_filesize

        # Generic hash.
        request.AddRequest(
            fp_type=rdf_client_action.FingerprintTuple.Type.FPT_GENERIC,
            hashers=[
                rdf_client_action.FingerprintTuple.HashType.MD5,
                rdf_client_action.FingerprintTuple.HashType.SHA1,
                rdf_client_action.FingerprintTuple.HashType.SHA256
            ])

        # Authenticode hash.
        request.AddRequest(
            fp_type=rdf_client_action.FingerprintTuple.Type.FPT_PE_COFF,
            hashers=[
                rdf_client_action.FingerprintTuple.HashType.MD5,
                rdf_client_action.FingerprintTuple.HashType.SHA1,
                rdf_client_action.FingerprintTuple.HashType.SHA256
            ])

        self.CallClient(self.fingerprint_file_mixin_client_action,
                        request,
                        next_state="ProcessFingerprint",
                        request_data=request_data)
Example #2
0
  def _ScheduleHashFile(self, index: int, pathspec: rdf_paths.PathSpec) -> None:
    """Schedules the HashFile Client Action.

    Args:
      index: Index of the current file to be hashed.
      pathspec: Pathspec of the current file to be hashed.
    """

    # Add the file tracker to the pending hashes list where it waits until the
    # hash comes back.
    self.state.pending_hashes[index] = {"index": index}

    request = rdf_client_action.FingerprintRequest(
        pathspec=pathspec, max_filesize=self.state.file_size)
    request.AddRequest(
        fp_type=rdf_client_action.FingerprintTuple.Type.FPT_GENERIC,
        hashers=[
            rdf_client_action.FingerprintTuple.HashType.MD5,
            rdf_client_action.FingerprintTuple.HashType.SHA1,
            rdf_client_action.FingerprintTuple.HashType.SHA256
        ])

    self.CallClient(
        server_stubs.HashFile,
        request,
        next_state=compatibility.GetName(self._ReceiveFileHash),
        request_data=dict(index=index))
Example #3
0
    def testHashFile(self):
        """Can we hash a file?"""
        path = os.path.join(self.base_path, "numbers.txt")
        p = rdf_paths.PathSpec(path=path,
                               pathtype=rdf_paths.PathSpec.PathType.OS)
        result = self.RunAction(
            file_fingerprint.FingerprintFile,
            rdf_client_action.FingerprintRequest(pathspec=p))
        types = result[0].matching_types
        fingers = {}
        for f in result[0].results:
            fingers[f["name"]] = f
        generic_sha256 = fingers["generic"]["sha256"]
        self.assertEqual(generic_sha256,
                         hashlib.sha256(open(path, "rb").read()).digest())

        # Make sure all fingers are listed in types and vice versa.
        t_map = {
            rdf_client_action.FingerprintTuple.Type.FPT_GENERIC: "generic",
            rdf_client_action.FingerprintTuple.Type.FPT_PE_COFF: "pecoff"
        }
        ti_map = dict((v, k) for k, v in iteritems(t_map))
        for t in types:
            self.assertIn(t_map[t], fingers)
        for f in fingers:
            self.assertIn(ti_map[f], types)

        self.assertEqual(result[0].pathspec.path, path)
Example #4
0
 def testMissingFile(self):
     """Fail on missing file?"""
     path = os.path.join(self.base_path, "this file does not exist")
     p = rdf_paths.PathSpec(path=path,
                            pathtype=rdf_paths.PathSpec.PathType.OS)
     self.assertRaises(IOError, self.RunAction,
                       file_fingerprint.FingerprintFile,
                       rdf_client_action.FingerprintRequest(pathspec=p))
Example #5
0
    def _TryToStartNextPathspec(self):
        """Try to schedule the next pathspec if there is enough capacity."""

        # Nothing to do here.
        if self.state.maximum_pending_files <= len(self.state.pending_files):
            return

        if self.state.maximum_pending_files <= len(self.state.pending_hashes):
            return

        try:
            index = self.state.next_pathspec_to_start
            pathspec = self.state.indexed_pathspecs[index]
            self.state.next_pathspec_to_start = index + 1
        except IndexError:
            # We did all the pathspecs, nothing left to do here.
            return

        # Add the file tracker to the pending hashes list where it waits until the
        # hash comes back.
        self.state.pending_hashes[index] = {"index": index}

        # First state the file, then hash the file.

        # TODO(hanuszczak): Support for old clients ends on 2021-01-01.
        # This conditional should be removed after that date.
        if not self.client_version or self.client_version >= 3221:
            stub = server_stubs.GetFileStat
            request = rdf_client_action.GetFileStatRequest(pathspec=pathspec)
            request.follow_symlink = True
            request_name = "GetFileStat"
        else:
            stub = server_stubs.StatFile
            request = rdf_client_action.ListDirRequest(pathspec=pathspec)
            request_name = "StatFile"

        self.CallClient(stub,
                        request,
                        next_state=compatibility.GetName(self._StoreStat),
                        request_data=dict(index=index,
                                          request_name=request_name))

        request = rdf_client_action.FingerprintRequest(
            pathspec=pathspec, max_filesize=self.state.file_size)
        request.AddRequest(
            fp_type=rdf_client_action.FingerprintTuple.Type.FPT_GENERIC,
            hashers=[
                rdf_client_action.FingerprintTuple.HashType.MD5,
                rdf_client_action.FingerprintTuple.HashType.SHA1,
                rdf_client_action.FingerprintTuple.HashType.SHA256
            ])

        self.CallClient(server_stubs.HashFile,
                        request,
                        next_state=compatibility.GetName(
                            self._ReceiveFileHash),
                        request_data=dict(index=index))