19 package org.sleuthkit.datamodel;
21 import java.io.BufferedReader;
22 import java.io.FileReader;
23 import java.io.IOException;
24 import java.text.DateFormat;
25 import java.text.SimpleDateFormat;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.GregorianCalendar;
29 import java.util.HashMap;
30 import java.util.HashSet;
31 import java.util.List;
34 import java.util.TimeZone;
35 import java.util.UUID;
68 private static class HandleCache {
73 private static final Object cacheLock =
new Object();
79 private static final Map<String, Long> imageHandleCache =
new HashMap<String, Long>();
85 private static final Map<Long, Map<Long, Long>> fsHandleCache =
new HashMap<Long, Map<Long, Long>>();
91 private static final Set<Long> fileHandleCache =
new HashSet<Long>();
93 private static final Map<Long, List<Long>> fileSystemToFileHandles =
new HashMap<Long, List<Long>>();
95 private static final String INVALID_FILE_HANDLE =
"Invalid file handle.";
103 private static void addFileHandle(
long fileHandle,
long fsHandle) {
104 synchronized (cacheLock) {
106 fileHandleCache.add(fileHandle);
109 if (fileSystemToFileHandles.containsKey(fsHandle)) {
110 fileSystemToFileHandles.get(fsHandle).add(fileHandle);
112 fileSystemToFileHandles.put(fsHandle,
new ArrayList<Long>(Arrays.asList(fileHandle)));
117 private static void removeFileHandle(
long fileHandle) {
118 synchronized (cacheLock) {
120 fileHandleCache.remove(fileHandle);
124 private static boolean isValidFileHandle(
long fileHandle) {
125 synchronized (cacheLock) {
126 return fileHandleCache.contains(fileHandle);
131 synchronized (cacheLock) {
135 for (Map<Long, Long> imageToFsMap : fsHandleCache.values()) {
136 for (Long fsHandle : imageToFsMap.values()) {
138 for (Long fileHandle : fileSystemToFileHandles.get(fsHandle)) {
142 closeFsNat(fsHandle);
149 for (Long imageHandle : imageHandleCache.values()) {
150 closeImgNat(imageHandle);
153 fsHandleCache.clear();
154 imageHandleCache.clear();
155 fileHandleCache.clear();
156 fileSystemToFileHandles.clear();
171 private final long caseDbPointer;
180 this.caseDbPointer = caseDbPointer;
190 HandleCache.closeHandlesAndClearCache();
217 long addImageInfo(
long deviceObjId, List<String> imageFilePaths, String timeZone)
throws TskCoreException {
219 long tskAutoDbPointer = initializeAddImgNat(caseDbPointer, timezoneLongToShort(timeZone),
false,
false,
false);
220 runOpenAndAddImgNat(tskAutoDbPointer, UUID.randomUUID().toString(), imageFilePaths.toArray(
new String[0]), imageFilePaths.size(), timeZone);
221 return commitAddImgNat(tskAutoDbPointer);
243 AddImageProcess initAddImageProcess(String timeZone,
boolean addUnallocSpace,
boolean skipFatFsOrphans, String imageCopyPath) {
244 return new AddImageProcess(timeZone, addUnallocSpace, skipFatFsOrphans, imageCopyPath);
253 private final String timeZone;
254 private final boolean addUnallocSpace;
255 private final boolean skipFatFsOrphans;
256 private final String imageWriterPath;
257 private volatile long tskAutoDbPointer;
258 private boolean isCanceled;
273 private AddImageProcess(String timeZone,
boolean addUnallocSpace,
boolean skipFatFsOrphans, String imageWriterPath) {
274 this.timeZone = timeZone;
275 this.addUnallocSpace = addUnallocSpace;
276 this.skipFatFsOrphans = skipFatFsOrphans;
277 this.imageWriterPath = imageWriterPath;
278 tskAutoDbPointer = 0;
279 this.isCanceled =
false;
300 long imageHandle = 0;
301 synchronized (
this) {
302 if (0 != tskAutoDbPointer) {
303 throw new TskCoreException(
"Add image process already started");
306 imageHandle =
openImage(imageFilePaths,
false);
307 tskAutoDbPointer = initAddImgNat(caseDbPointer, timezoneLongToShort(timeZone), addUnallocSpace, skipFatFsOrphans);
309 if (0 == tskAutoDbPointer) {
310 throw new TskCoreException(
"initAddImgNat returned a NULL TskAutoDb pointer");
313 if (imageHandle != 0) {
314 runAddImgNat(tskAutoDbPointer, deviceId, imageHandle, timeZone, imageWriterPath);
327 public synchronized void stop() throws TskCoreException {
329 if (tskAutoDbPointer != 0) {
330 stopAddImgNat(tskAutoDbPointer);
341 public synchronized void revert() throws TskCoreException {
342 if (tskAutoDbPointer == 0) {
343 throw new TskCoreException(
"AddImgProcess::revert: AutoDB pointer is NULL");
346 revertAddImgNat(tskAutoDbPointer);
348 tskAutoDbPointer = 0;
360 public synchronized long commit() throws TskCoreException {
361 if (tskAutoDbPointer == 0) {
362 throw new TskCoreException(
"AddImgProcess::commit: AutoDB pointer is NULL");
365 long id = commitAddImgNat(tskAutoDbPointer);
367 tskAutoDbPointer = 0;
378 return tskAutoDbPointer == 0 ?
"" : getCurDirNat(tskAutoDbPointer);
398 run(null, imageFilePaths);
416 return new CaseDbHandle(newCaseDbNat(path));
431 static CaseDbHandle newCaseDb(String databaseName, CaseDbConnectionInfo info)
throws TskCoreException {
432 return new CaseDbHandle(newCaseDbMultiNat(info.getHost(), info.getPort(), info.getUserName(), info.getPassword(), info.getDbType().ordinal(), databaseName));
446 static CaseDbHandle openCaseDb(String path)
throws TskCoreException {
447 return new CaseDbHandle(openCaseDbNat(path));
462 static CaseDbHandle openCaseDb(String databaseName, CaseDbConnectionInfo info)
throws TskCoreException {
463 return new CaseDbHandle(openCaseDbMultiNat(info.getHost(), info.getPort(), info.getUserName(), info.getPassword(), info.getDbType().ordinal(), databaseName));
472 return getVersionNat();
479 startVerboseLoggingNat(logPath);
515 StringBuilder keyBuilder =
new StringBuilder();
516 for (
int i = 0; i < imageFiles.length; ++i) {
517 keyBuilder.append(imageFiles[i]);
519 final String imageKey = keyBuilder.toString();
521 synchronized (HandleCache.cacheLock) {
523 if (!useCache && HandleCache.imageHandleCache.containsKey(imageKey)) {
524 long tempImageHandle = HandleCache.imageHandleCache.get(imageKey);
525 HandleCache.fsHandleCache.remove(tempImageHandle);
526 HandleCache.imageHandleCache.remove(imageKey);
529 if (useCache && HandleCache.imageHandleCache.containsKey(imageKey))
531 imageHandle = HandleCache.imageHandleCache.get(imageKey);
534 imageHandle = openImgNat(imageFiles, imageFiles.length);
535 HandleCache.fsHandleCache.put(imageHandle,
new HashMap<Long, Long>());
536 HandleCache.imageHandleCache.put(imageKey, imageHandle);
555 return openVsNat(imgHandle, vsOffset);
572 return openVolNat(vsHandle, volId);
589 synchronized (HandleCache.cacheLock) {
590 final Map<Long, Long> imgOffSetToFsHandle = HandleCache.fsHandleCache.get(imgHandle);
591 if (imgOffSetToFsHandle.containsKey(fsOffset)) {
593 fsHandle = imgOffSetToFsHandle.get(fsOffset);
595 fsHandle = openFsNat(imgHandle, fsOffset);
597 imgOffSetToFsHandle.put(fsOffset, fsHandle);
628 long fileHandle = openFileNat(fsHandle, fileId, attrType.getValue(), convertSignedToUnsigned(attrId));
629 HandleCache.addFileHandle(fileHandle, fsHandle);
640 private static int convertSignedToUnsigned(
int val) {
665 return readImgNat(imgHandle, readBuffer, offset, len);
683 return readVsNat(vsHandle, readBuffer, offset, len);
702 return readVolNat(volHandle, readBuffer, offset, len);
721 return readFsNat(fsHandle, readBuffer, offset, len);
728 private enum TSK_FS_FILE_READ_OFFSET_TYPE_ENUM {
732 private final int val;
734 TSK_FS_FILE_READ_OFFSET_TYPE_ENUM(
int val) {
758 if (!HandleCache.isValidFileHandle(fileHandle)) {
762 return readFileNat(fileHandle, readBuffer, offset, TSK_FS_FILE_READ_OFFSET_TYPE_ENUM.START_OF_FILE.getValue(), len);
780 if (!HandleCache.isValidFileHandle(fileHandle)) {
784 return readFileNat(fileHandle, readBuffer, offset, TSK_FS_FILE_READ_OFFSET_TYPE_ENUM.START_OF_SLACK.getValue(), len);
798 if (!HandleCache.isValidFileHandle(fileHandle)) {
803 java.io.File tmp = java.io.File.createTempFile(
"tsk",
".txt");
805 saveFileMetaDataTextNat(fileHandle, tmp.getAbsolutePath());
807 FileReader fr =
new FileReader(tmp.getAbsolutePath());
808 BufferedReader textReader =
new BufferedReader(fr);
810 List<String> lines =
new ArrayList<String>();
812 String line = textReader.readLine();
822 }
catch (IOException ex) {
823 throw new TskCoreException(
"Error reading istat output: " + ex.getLocalizedMessage());
846 closeVsNat(vsHandle);
867 if (!HandleCache.isValidFileHandle(fileHandle)) {
871 closeFileNat(fileHandle);
872 HandleCache.removeFileHandle(fileHandle);
883 hashDbCreateIndexNat(dbHandle);
896 return hashDbIndexExistsNat(dbHandle);
910 return hashDbIsReindexableNat(dbHandle);
923 return hashDbPathNat(dbHandle);
936 return hashDbIndexPathNat(dbHandle);
940 return hashDbOpenNat(path);
953 return hashDbNewNat(path);
974 hashDbClose(dbHandle);
985 return hashDbGetDisplayName(dbHandle);
999 return hashDbLookup(hash, dbHandle);
1014 return hashDbLookupVerbose(hash, dbHandle);
1030 hashDbAddEntryNat(filename, md5, sha1, sha256, comment, dbHandle);
1034 hashDbBeginTransactionNat(dbHandle);
1037 hashDbAddEntryNat(entry.getFileName(), entry.getMd5Hash(), entry.getSha1Hash(), entry.getSha256Hash(), entry.getComment(), dbHandle);
1039 hashDbCommitTransactionNat(dbHandle);
1042 hashDbRollbackTransactionNat(dbHandle);
1052 return hashDbIsUpdateableNat(dbHandle);
1056 return hashDbIsIdxOnlyNat(dbHandle);
1068 private static String timezoneLongToShort(String timezoneLongForm) {
1069 if (timezoneLongForm == null || timezoneLongForm.isEmpty()) {
1073 String timezoneShortForm;
1074 TimeZone zone = TimeZone.getTimeZone(timezoneLongForm);
1075 int offset = zone.getRawOffset() / 1000;
1076 int hour = offset / 3600;
1077 int min = (offset % 3600) / 60;
1078 DateFormat dfm =
new SimpleDateFormat(
"z");
1079 dfm.setTimeZone(zone);
1080 boolean hasDaylight = zone.useDaylightTime();
1081 String first = dfm.format(
new GregorianCalendar(2010, 1, 1).getTime()).substring(0, 3);
1082 String second = dfm.format(
new GregorianCalendar(2011, 6, 6).getTime()).substring(0, 3);
1083 int mid = hour * -1;
1084 timezoneShortForm = first + Integer.toString(mid);
1086 timezoneShortForm = timezoneShortForm +
":" + (min < 10 ?
"0" :
"") + Integer.toString(min);
1089 timezoneShortForm += second;
1091 return timezoneShortForm;
1103 return finishImageWriterNat(imgHandle);
1114 return getFinishImageProgressNat(imgHandle);
1123 cancelFinishImageNat(imgHandle);
1138 return findDeviceSizeNat(devPath);
1142 return isImageSupportedNat(imagePath);
1145 private static native String getVersionNat();
1147 private static native
void startVerboseLoggingNat(String logPath);
1149 private static native
long newCaseDbNat(String dbPath)
throws TskCoreException;
1151 private static native
long newCaseDbMultiNat(String hostNameOrIP, String portNumber, String userName, String password,
int dbTypeOrdinal, String databaseName);
1153 private static native
long openCaseDbMultiNat(String hostNameOrIP, String portNumber, String userName, String password,
int dbTypeOrdinal, String databaseName);
1155 private static native
long openCaseDbNat(String path)
throws TskCoreException;
1157 private static native
void closeCaseDbNat(
long db)
throws TskCoreException;
1159 private static native
int hashDbOpenNat(String hashDbPath)
throws TskCoreException;
1161 private static native
int hashDbNewNat(String hashDbPath)
throws TskCoreException;
1163 private static native
int hashDbBeginTransactionNat(
int dbHandle)
throws TskCoreException;
1165 private static native
int hashDbCommitTransactionNat(
int dbHandle)
throws TskCoreException;
1167 private static native
int hashDbRollbackTransactionNat(
int dbHandle)
throws TskCoreException;
1169 private static native
int hashDbAddEntryNat(String filename, String hashMd5, String hashSha1, String hashSha256, String comment,
int dbHandle)
throws TskCoreException;
1171 private static native
boolean hashDbIsUpdateableNat(
int dbHandle);
1173 private static native
boolean hashDbIsReindexableNat(
int dbHandle);
1175 private static native String hashDbPathNat(
int dbHandle);
1177 private static native String hashDbIndexPathNat(
int dbHandle);
1179 private static native String hashDbGetDisplayName(
int dbHandle)
throws TskCoreException;
1181 private static native
void hashDbCloseAll() throws TskCoreException;
1183 private static native
void hashDbClose(
int dbHandle) throws TskCoreException;
1185 private static native
void hashDbCreateIndexNat(
int dbHandle) throws TskCoreException;
1187 private static native
boolean hashDbIndexExistsNat(
int dbHandle) throws TskCoreException;
1189 private static native
boolean hashDbIsIdxOnlyNat(
int dbHandle) throws TskCoreException;
1191 private static native
boolean hashDbLookup(String hash,
int dbHandle) throws TskCoreException;
1193 private static native
HashHitInfo hashDbLookupVerbose(String hash,
int dbHandle) throws TskCoreException;
1195 private static native
long initAddImgNat(
long db, String timezone,
boolean addUnallocSpace,
boolean skipFatFsOrphans) throws TskCoreException;
1197 private static native
long initializeAddImgNat(
long db, String timezone,
boolean addFileSystems,
boolean addUnallocSpace,
boolean skipFatFsOrphans) throws TskCoreException;
1199 private static native
void runOpenAndAddImgNat(
long process, String deviceId, String[] imgPath,
int splits, String timezone) throws TskCoreException,
TskDataException;
1201 private static native
void runAddImgNat(
long process, String deviceId,
long a_img_info, String timeZone, String imageWriterPath) throws TskCoreException, TskDataException;
1203 private static native
void stopAddImgNat(
long process) throws TskCoreException;
1205 private static native
void revertAddImgNat(
long process) throws TskCoreException;
1207 private static native
long commitAddImgNat(
long process) throws TskCoreException;
1209 private static native
long openImgNat(String[] imgPath,
int splits) throws TskCoreException;
1211 private static native
long openVsNat(
long imgHandle,
long vsOffset) throws TskCoreException;
1213 private static native
long openVolNat(
long vsHandle,
long volId) throws TskCoreException;
1215 private static native
long openFsNat(
long imgHandle,
long fsId) throws TskCoreException;
1217 private static native
long openFileNat(
long fsHandle,
long fileId,
int attrType,
int attrId) throws TskCoreException;
1219 private static native
int readImgNat(
long imgHandle, byte[] readBuffer,
long offset,
long len) throws TskCoreException;
1221 private static native
int readVsNat(
long vsHandle, byte[] readBuffer,
long offset,
long len) throws TskCoreException;
1223 private static native
int readVolNat(
long volHandle, byte[] readBuffer,
long offset,
long len) throws TskCoreException;
1225 private static native
int readFsNat(
long fsHandle, byte[] readBuffer,
long offset,
long len) throws TskCoreException;
1227 private static native
int readFileNat(
long fileHandle, byte[] readBuffer,
long offset,
int offset_type,
long len) throws TskCoreException;
1229 private static native
int saveFileMetaDataTextNat(
long fileHandle, String fileName) throws TskCoreException;
1231 private static native
void closeImgNat(
long imgHandle);
1233 private static native
void closeVsNat(
long vsHandle);
1235 private static native
void closeFsNat(
long fsHandle);
1237 private static native
void closeFileNat(
long fileHandle);
1239 private static native
long findDeviceSizeNat(String devicePath) throws TskCoreException;
1241 private static native String getCurDirNat(
long process);
1243 private static native
boolean isImageSupportedNat(String imagePath);
1245 private static native
int finishImageWriterNat(
long a_img_info);
1247 private static native
int getFinishImageProgressNat(
long a_img_info);
1249 private static native
void cancelFinishImageNat(
long a_img_info);
static int readImg(long imgHandle, byte[] readBuffer, long offset, long len)
static String getHashDatabaseIndexPath(int dbHandle)
static int readVs(long vsHandle, byte[] readBuffer, long offset, long len)
static void createLookupIndexForHashDatabase(int dbHandle)
static void addToHashDatabase(String filename, String md5, String sha1, String sha256, String comment, int dbHandle)
static int createHashDatabase(String path)
static void closeFs(long fsHandle)
static void cancelFinishImage(long imgHandle)
static long openFile(long fsHandle, long fileId, TSK_FS_ATTR_TYPE_ENUM attrType, int attrId)
void run(String deviceId, String[] imageFilePaths)
static int readFile(long fileHandle, byte[] readBuffer, long offset, long len)
static int finishImageWriter(long imgHandle)
static HashHitInfo lookupInHashDatabaseVerbose(String hash, int dbHandle)
static long openVs(long imgHandle, long vsOffset)
synchronized long commit()
static boolean hashDatabaseIsIndexOnly(int dbHandle)
synchronized void revert()
static boolean isImageSupported(String imagePath)
static int readVsPart(long volHandle, byte[] readBuffer, long offset, long len)
static boolean loadSleuthkitJNI()
static void closeVs(long vsHandle)
static long openImage(String[] imageFiles)
static long findDeviceSize(String devPath)
static String getHashDatabaseDisplayName(int dbHandle)
static List< String > getFileMetaDataText(long fileHandle)
static void closeImg(long imgHandle)
static long openFs(long imgHandle, long fsOffset)
void run(String[] imageFilePaths)
synchronized String currentDirectory()
static int getFinishImageProgress(long imgHandle)
static int openHashDatabase(String path)
static void closeFile(long fileHandle)
static boolean lookupInHashDatabase(String hash, int dbHandle)
static boolean hashDatabaseHasLookupIndex(int dbHandle)
static long openVsPart(long vsHandle, long volId)
static int readFileSlack(long fileHandle, byte[] readBuffer, long offset, long len)
static boolean isUpdateableHashDatabase(int dbHandle)
static void addToHashDatabase(List< HashEntry > hashes, int dbHandle)
static void closeAllHashDatabases()
static boolean hashDatabaseCanBeReindexed(int dbHandle)
static String getVersion()
static void startVerboseLogging(String logPath)
static int readFs(long fsHandle, byte[] readBuffer, long offset, long len)
static String getHashDatabasePath(int dbHandle)
static void closeHashDatabase(int dbHandle)