def StartFileFetch(self, pathspec, request_data=None): """The entry point for this flow mixin - Schedules new file transfer.""" # Create an index so we can find this pathspec later. index = self.GenerateIndex(pathspec) self.state.indexed_pathspecs[index] = pathspec request_data = request_data or {} request_data["index"] = index self.CallClient("StatFile", pathspec=pathspec, next_state="StoreStat", request_data=request_data) request = rdf_client.FingerprintRequest( pathspec=pathspec, max_filesize=self.state.file_size) request.AddRequest( fp_type=rdf_client.FingerprintTuple.Type.FPT_GENERIC, hashers=[ rdf_client.FingerprintTuple.HashType.MD5, rdf_client.FingerprintTuple.HashType.SHA1, rdf_client.FingerprintTuple.HashType.SHA256 ]) self.CallClient("HashFile", request, next_state="ReceiveFileHash", request_data=request_data)
def FingerprintFile(self, pathspec, max_filesize=None, request_data=None): """Launch a fingerprint client action.""" request = rdf_client.FingerprintRequest(pathspec=pathspec) if max_filesize is not None: request.max_filesize = max_filesize # Generic hash. request.AddRequest( fp_type=rdf_client.FingerprintTuple.Type.FPT_GENERIC, hashers=[ rdf_client.FingerprintTuple.HashType.MD5, rdf_client.FingerprintTuple.HashType.SHA1, rdf_client.FingerprintTuple.HashType.SHA256 ]) # Authenticode hash. request.AddRequest( fp_type=rdf_client.FingerprintTuple.Type.FPT_PE_COFF, hashers=[ rdf_client.FingerprintTuple.HashType.MD5, rdf_client.FingerprintTuple.HashType.SHA1, rdf_client.FingerprintTuple.HashType.SHA256 ]) self.CallClient( self.fingerprint_file_mixin_client_action, request, next_state="ProcessFingerprint", request_data=request_data)
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.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.FingerprintTuple.Type.FPT_GENERIC: "generic", rdf_client.FingerprintTuple.Type.FPT_PE_COFF: "pecoff" } ti_map = dict((v, k) for k, v in t_map.iteritems()) for t in types: self.assertTrue(t_map[t] in fingers) for f in fingers: self.assertTrue(ti_map[f] in types) self.assertEqual(result[0].pathspec.path, path)
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, "FingerprintFile", rdf_client.FingerprintRequest(pathspec=p))
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 self.client_version >= 3221: stub = server_stubs.GetFileStat request = rdf_client.GetFileStatRequest(pathspec=pathspec) else: stub = server_stubs.StatFile request = rdf_client.ListDirRequest(pathspec=pathspec) self.CallClient(stub, request, next_state="StoreStat", request_data=dict(index=index)) request = rdf_client.FingerprintRequest( pathspec=pathspec, max_filesize=self.state.file_size) request.AddRequest( fp_type=rdf_client.FingerprintTuple.Type.FPT_GENERIC, hashers=[ rdf_client.FingerprintTuple.HashType.MD5, rdf_client.FingerprintTuple.HashType.SHA1, rdf_client.FingerprintTuple.HashType.SHA256 ]) self.CallClient(server_stubs.HashFile, request, next_state="ReceiveFileHash", request_data=dict(index=index))
def StartFileFetch(self, pathspec, vfs_urn, request_data=None): """The entry point for this flow mixin - Schedules new file transfer.""" request_data = request_data or {} request_data["vfs_urn"] = vfs_urn self.CallClient("StatFile", pathspec=pathspec, next_state="StoreStat", request_data=request_data) request = rdf_client.FingerprintRequest(pathspec=pathspec, max_filesize=self.state.file_size) request.AddRequest( fp_type=rdf_client.FingerprintTuple.Type.FPT_GENERIC, hashers=[rdf_client.FingerprintTuple.HashType.MD5, rdf_client.FingerprintTuple.HashType.SHA1, rdf_client.FingerprintTuple.HashType.SHA256]) self.CallClient("HashFile", request, next_state="ReceiveFileHash", request_data=request_data)
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. self.CallClient( server_stubs.StatFile, pathspec=pathspec, next_state="StoreStat", request_data=dict(index=index)) request = rdf_client.FingerprintRequest( pathspec=pathspec, max_filesize=self.state.file_size) request.AddRequest( fp_type=rdf_client.FingerprintTuple.Type.FPT_GENERIC, hashers=[ rdf_client.FingerprintTuple.HashType.MD5, rdf_client.FingerprintTuple.HashType.SHA1, rdf_client.FingerprintTuple.HashType.SHA256 ]) self.CallClient( server_stubs.HashFile, request, next_state="ReceiveFileHash", request_data=dict(index=index))