Sleuth Kit Java Bindings (JNI)  4.10.0
Java bindings for using The Sleuth Kit
TskCaseDbBridge.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2020 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.datamodel;
20 
21 import java.sql.PreparedStatement;
22 import java.sql.SQLException;
23 import java.sql.Statement;
24 import org.apache.commons.lang3.StringUtils;
25 import java.util.List;
26 import java.util.Arrays;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.LinkedList;
30 import java.util.Map;
31 import java.util.Objects;
32 import java.util.Queue;
33 import java.util.logging.Level;
34 import java.util.logging.Logger;
36 
46 class TskCaseDbBridge {
47 
48  private static final Logger logger = Logger.getLogger(TskCaseDbBridge.class.getName());
49 
50  private final SleuthkitCase caseDb;
51  private CaseDbTransaction trans = null;
52  private final AddDataSourceCallbacks addDataSourceCallbacks;
53 
54  private final Map<Long, Long> fsIdToRootDir = new HashMap<>();
55  private final Map<Long, TskData.TSK_FS_TYPE_ENUM> fsIdToFsType = new HashMap<>();
56  private final Map<ParentCacheKey, Long> parentDirCache = new HashMap<>();
57 
58  private static final long BATCH_FILE_THRESHOLD = 500;
59  private final Queue<FileInfo> batchedFiles = new LinkedList<>();
60  private final Queue<LayoutRangeInfo> batchedLayoutRanges = new LinkedList<>();
61  private final List<Long> layoutFileIds = new ArrayList<>();
62 
63  TskCaseDbBridge(SleuthkitCase caseDb, AddDataSourceCallbacks addDataSourceCallbacks) {
64  this.caseDb = caseDb;
65  this.addDataSourceCallbacks = addDataSourceCallbacks;
66  trans = null;
67  }
68 
74  private void beginTransaction() throws TskCoreException {
75  trans = caseDb.beginTransaction();
76  }
77 
83  private void commitTransaction() throws TskCoreException {
84  trans.commit();
85  trans = null;
86  }
87 
91  private void revertTransaction() {
92  try {
93  if (trans != null) {
94  trans.rollback();
95  trans = null;
96  }
97  } catch (TskCoreException ex) {
98  logger.log(Level.SEVERE, "Error rolling back transaction", ex);
99  }
100  }
101 
105  void finish() {
106  addBatchedFilesToDb();
107  addBatchedLayoutRangesToDb();
108  processLayoutFiles();
109  }
110 
129  long addImageInfo(int type, long ssize, String timezone,
130  long size, String md5, String sha1, String sha256, String deviceId,
131  String collectionDetails, String[] paths) {
132  try {
133  beginTransaction();
134  long objId = addImageToDb(TskData.TSK_IMG_TYPE_ENUM.valueOf(type), ssize, size,
135  timezone, md5, sha1, sha256, deviceId, collectionDetails, trans);
136  for (int i = 0;i < paths.length;i++) {
137  addImageNameToDb(objId, paths[i], i, trans);
138  }
139  commitTransaction();
140  return objId;
141  } catch (TskCoreException ex) {
142  logger.log(Level.SEVERE, "Error adding image to the database", ex);
143  revertTransaction();
144  return -1;
145  }
146  }
147 
154  void addAcquisitionDetails(long imgId, String details) {
155  try {
156  beginTransaction();
157  caseDb.setAcquisitionDetails(imgId, details, trans);
158  commitTransaction();
159  } catch (TskCoreException ex) {
160  logger.log(Level.SEVERE, "Error adding image details \"" + details + "\" to image with ID " + imgId, ex);
161  revertTransaction();
162  }
163  }
164 
176  long addVsInfo(long parentObjId, int vsType, long imgOffset, long blockSize) {
177  try {
178  beginTransaction();
179  VolumeSystem vs = caseDb.addVolumeSystem(parentObjId, TskData.TSK_VS_TYPE_ENUM.valueOf(vsType), imgOffset, blockSize, trans);
180  commitTransaction();
181  return vs.getId();
182  } catch (TskCoreException ex) {
183  logger.log(Level.SEVERE, "Error adding volume system to the database - parent obj ID: " + parentObjId
184  + ", image offset: " + imgOffset, ex);
185  revertTransaction();
186  return -1;
187  }
188  }
189 
203  long addVolume(long parentObjId, long addr, long start, long length, String desc,
204  long flags) {
205  try {
206  beginTransaction();
207  Volume vol = caseDb.addVolume(parentObjId, addr, start, length, desc, flags, trans);
208  commitTransaction();
209  return vol.getId();
210  } catch (TskCoreException ex) {
211  logger.log(Level.SEVERE, "Error adding volume to the database - parent object ID: " + parentObjId
212  + ", addr: " + addr, ex);
213  revertTransaction();
214  return -1;
215  }
216  }
217 
227  long addPool(long parentObjId, int poolType) {
228  try {
229  beginTransaction();
230  Pool pool = caseDb.addPool(parentObjId, TskData.TSK_POOL_TYPE_ENUM.valueOf(poolType), trans);
231  commitTransaction();
232  return pool.getId();
233  } catch (TskCoreException ex) {
234  logger.log(Level.SEVERE, "Error adding pool to the database - parent object ID: " + parentObjId, ex);
235  revertTransaction();
236  return -1;
237  }
238  }
239 
255  long addFileSystem(long parentObjId, long imgOffset, int fsType, long blockSize, long blockCount,
256  long rootInum, long firstInum, long lastInum) {
257  try {
258  beginTransaction();
259  FileSystem fs = caseDb.addFileSystem(parentObjId, imgOffset, TskData.TSK_FS_TYPE_ENUM.valueOf(fsType), blockSize, blockCount,
260  rootInum, firstInum, lastInum, null, trans);
261  commitTransaction();
262  fsIdToFsType.put(fs.getId(), TskData.TSK_FS_TYPE_ENUM.valueOf(fsType));
263  return fs.getId();
264  } catch (TskCoreException ex) {
265  logger.log(Level.SEVERE, "Error adding file system to the database - parent object ID: " + parentObjId
266  + ", offset: " + imgOffset, ex);
267  revertTransaction();
268  return -1;
269  }
270  }
271 
312  long addFile(long parentObjId,
313  long fsObjId, long dataSourceObjId,
314  int fsType,
315  int attrType, int attrId, String name,
316  long metaAddr, long metaSeq,
317  int dirType, int metaType, int dirFlags, int metaFlags,
318  long size,
319  long crtime, long ctime, long atime, long mtime,
320  int meta_mode, int gid, int uid,
321  String escaped_path, String extension,
322  long seq, long parMetaAddr, long parSeq) {
323 
324  // Add the new file to the list
325  batchedFiles.add(new FileInfo(parentObjId,
326  fsObjId, dataSourceObjId,
327  fsType,
328  attrType, attrId, name,
329  metaAddr, metaSeq,
330  dirType, metaType, dirFlags, metaFlags,
331  size,
332  crtime, ctime, atime, mtime,
333  meta_mode, gid, uid,
334  escaped_path, extension,
335  seq, parMetaAddr, parSeq));
336 
337  // Add the current files to the database if we've exceeded the threshold or if we
338  // have the root folder.
339  if ((fsObjId == parentObjId)
340  || (batchedFiles.size() > BATCH_FILE_THRESHOLD)) {
341  return addBatchedFilesToDb();
342  }
343  return 0;
344  }
345 
351  private long addBatchedFilesToDb() {
352  List<Long> newObjIds = new ArrayList<>();
353  try {
354  beginTransaction();
355  FileInfo fileInfo;
356  while ((fileInfo = batchedFiles.poll()) != null) {
357  long computedParentObjId = fileInfo.parentObjId;
358  try {
359  // If we weren't given the parent object ID, look it up
360  if (fileInfo.parentObjId == 0) {
361  computedParentObjId = getParentObjId(fileInfo);
362  }
363 
364  long objId = addFileToDb(computedParentObjId,
365  fileInfo.fsObjId, fileInfo.dataSourceObjId,
366  fileInfo.fsType,
367  fileInfo.attrType, fileInfo.attrId, fileInfo.name,
368  fileInfo.metaAddr, fileInfo.metaSeq,
369  fileInfo.dirType, fileInfo.metaType, fileInfo.dirFlags, fileInfo.metaFlags,
370  fileInfo.size,
371  fileInfo.crtime, fileInfo.ctime, fileInfo.atime, fileInfo.mtime,
372  fileInfo.meta_mode, fileInfo.gid, fileInfo.uid,
373  null, TskData.FileKnown.UNKNOWN,
374  fileInfo.escaped_path, fileInfo.extension,
375  false, trans);
376  if (fileInfo.fsObjId != fileInfo.parentObjId) {
377  // Add new file ID to the list to send to ingest unless it is the root folder
378  newObjIds.add(objId);
379  }
380 
381  // If we're adding the root directory for the file system, cache it
382  if (fileInfo.parentObjId == fileInfo.fsObjId) {
383  fsIdToRootDir.put(fileInfo.fsObjId, objId);
384  }
385 
386  // If the file is a directory, cache the object ID
387  if ((fileInfo.metaType == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR.getValue()
388  || (fileInfo.metaType == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR.getValue()))
389  && (fileInfo.name != null)
390  && ! fileInfo.name.equals(".")
391  && ! fileInfo.name.equals("..")) {
392  String dirName = fileInfo.escaped_path + fileInfo.name;
393  ParentCacheKey key = new ParentCacheKey(fileInfo.fsObjId, fileInfo.metaAddr, fileInfo.seq, dirName);
394  parentDirCache.put(key, objId);
395  }
396  } catch (TskCoreException ex) {
397  logger.log(Level.SEVERE, "Error adding file to the database - parent object ID: " + computedParentObjId
398  + ", file system object ID: " + fileInfo.fsObjId + ", name: " + fileInfo.name, ex);
399  }
400  }
401  commitTransaction();
402  try {
403  addDataSourceCallbacks.onFilesAdded(newObjIds);
404  } catch (Exception ex) {
405  // Exception firewall to prevent unexpected return to the native code
406  logger.log(Level.SEVERE, "Unexpected error from files added callback", ex);
407  }
408  } catch (TskCoreException ex) {
409  logger.log(Level.SEVERE, "Error adding batched files to database", ex);
410  revertTransaction();
411  return -1;
412  }
413  return 0;
414  }
415 
425  private long getParentObjId(FileInfo fileInfo) throws TskCoreException {
426  // Remove the final slash from the path unless we're in the root folder
427  String parentPath = fileInfo.escaped_path;
428  if(parentPath.endsWith("/") && ! parentPath.equals("/")) {
429  parentPath = parentPath.substring(0, parentPath.lastIndexOf('/'));
430  }
431 
432  // Look up the parent
433  ParentCacheKey key = new ParentCacheKey(fileInfo.fsObjId, fileInfo.parMetaAddr, fileInfo.parSeq, parentPath);
434  if (parentDirCache.containsKey(key)) {
435  return parentDirCache.get(key);
436  } else {
437  // There's no reason to do a database query since every folder added is being
438  // stored in the cache.
439  throw new TskCoreException("Parent not found in cache (fsObjId: " +fileInfo.fsObjId + ", parMetaAddr: " + fileInfo.parMetaAddr
440  + ", parSeq: " + fileInfo.parSeq + ", parentPath: " + parentPath + ")");
441  }
442  }
443 
457  long addLayoutFile(long parentObjId,
458  long fsObjId, long dataSourceObjId,
459  int fileType,
460  String name, long size) {
461  try {
462 
463  // The file system may be null for layout files
464  Long fsObjIdForDb = fsObjId;
465  if (fsObjId == 0) {
466  fsObjIdForDb = null;
467  }
468 
469  beginTransaction();
470  long objId = addFileToDb(parentObjId,
471  fsObjIdForDb, dataSourceObjId,
472  fileType,
473  null, null, name,
474  null, null,
475  TskData.TSK_FS_NAME_TYPE_ENUM.REG.getValue(),
476  TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue(),
477  TskData.TSK_FS_NAME_FLAG_ENUM.UNALLOC.getValue(),
478  TskData.TSK_FS_META_FLAG_ENUM.UNALLOC.getValue(),
479  size,
480  null, null, null, null,
481  null, null, null,
482  null, TskData.FileKnown.UNKNOWN,
483  null, null,
484  true, trans);
485  commitTransaction();
486 
487  // Store the layout file ID for later processing
488  layoutFileIds.add(objId);
489 
490  return objId;
491  } catch (TskCoreException ex) {
492  logger.log(Level.SEVERE, "Error adding layout file to the database - parent object ID: " + parentObjId
493  + ", file system object ID: " + fsObjId + ", name: " + name, ex);
494  revertTransaction();
495  return -1;
496  }
497  }
498 
510  long addLayoutFileRange(long objId, long byteStart, long byteLen, long seq) {
511  batchedLayoutRanges.add(new LayoutRangeInfo(objId, byteStart, byteLen, seq));
512 
513  if (batchedLayoutRanges.size() > BATCH_FILE_THRESHOLD) {
514  return addBatchedLayoutRangesToDb();
515  }
516  return 0;
517  }
518 
524  private long addBatchedLayoutRangesToDb() {
525  try {
526  beginTransaction();
527  LayoutRangeInfo range;
528  while ((range = batchedLayoutRanges.poll()) != null) {
529  try {
530  addLayoutFileRangeToDb(range.objId, range.byteStart, range.byteLen, range.seq, trans);
531  } catch (TskCoreException ex) {
532  logger.log(Level.SEVERE, "Error adding layout file range to the database - layout file ID: " + range.objId
533  + ", byte start: " + range.byteStart + ", length: " + range.byteLen + ", seq: " + range.seq, ex);
534  }
535  }
536  commitTransaction();
537  return 0;
538  } catch (TskCoreException ex) {
539  logger.log(Level.SEVERE, "Error adding batched files to database", ex);
540  revertTransaction();
541  return -1;
542  }
543  }
544 
550  void processLayoutFiles() {
551  addDataSourceCallbacks.onFilesAdded(layoutFileIds);
552  layoutFileIds.clear();
553  }
554 
564  long addUnallocFsBlockFilesParent(long fsObjId, String name) {
565  try {
566  if (! fsIdToRootDir.containsKey(fsObjId)) {
567  logger.log(Level.SEVERE, "Error - root directory for file system ID {0} not found", fsObjId);
568  return -1;
569  }
570  beginTransaction();
571  VirtualDirectory dir = caseDb.addVirtualDirectory(fsIdToRootDir.get(fsObjId), name, trans);
572  commitTransaction();
573  addDataSourceCallbacks.onFilesAdded(Arrays.asList(dir.getId()));
574  return dir.getId();
575  } catch (TskCoreException ex) {
576  logger.log(Level.SEVERE, "Error creating virtual directory " + name + " under file system ID " + fsObjId, ex);
577  revertTransaction();
578  return -1;
579  }
580  }
581 
585  private class ParentCacheKey {
586  long fsObjId;
587  long metaAddr;
588  long seqNum;
589  String path;
590 
600  ParentCacheKey(long fsObjId, long metaAddr, long seqNum, String path) {
601  this.fsObjId = fsObjId;
602  this.metaAddr = metaAddr;
603  if (fsIdToFsType.containsKey(fsObjId)
604  && (fsIdToFsType.get(fsObjId).equals(TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_NTFS)
605  || fsIdToFsType.get(fsObjId).equals(TskData.TSK_FS_TYPE_ENUM.TSK_FS_TYPE_NTFS_DETECT))) {
606  this.seqNum = seqNum;
607  } else {
608  this.seqNum = 0;
609  }
610  this.path = path;
611  }
612 
613  @Override
614  public boolean equals(Object obj) {
615  if (! (obj instanceof ParentCacheKey)) {
616  return false;
617  }
618 
619  ParentCacheKey otherKey = (ParentCacheKey) obj;
620  if (this.fsObjId != otherKey.fsObjId
621  || this.metaAddr != otherKey.metaAddr
622  || this.seqNum != otherKey.seqNum) {
623  return false;
624  }
625 
626  return StringUtils.equals(this.path, otherKey.path);
627  }
628 
629  @Override
630  public int hashCode() {
631  int hash = 3;
632  hash = 31 * hash + (int) (this.fsObjId ^ (this.fsObjId >>> 32));
633  hash = 31 * hash + (int) (this.metaAddr ^ (this.metaAddr >>> 32));
634  hash = 31 * hash + (int) (this.seqNum ^ (this.seqNum >>> 32));
635  hash = 31 * hash + Objects.hashCode(this.path);
636  return hash;
637  }
638  }
639 
644  private class LayoutRangeInfo {
645  long objId;
646  long byteStart;
647  long byteLen;
648  long seq;
649 
650  LayoutRangeInfo(long objId, long byteStart, long byteLen, long seq) {
651  this.objId = objId;
652  this.byteStart = byteStart;
653  this.byteLen = byteLen;
654  this.seq = seq;
655  }
656  }
657 
662  private class FileInfo {
663  long parentObjId;
664  long fsObjId;
665  long dataSourceObjId;
666  int fsType;
667  int attrType;
668  int attrId;
669  String name;
670  long metaAddr;
671  long metaSeq;
672  int dirType;
673  int metaType;
674  int dirFlags;
675  int metaFlags;
676  long size;
677  long crtime;
678  long ctime;
679  long atime;
680  long mtime;
681  int meta_mode;
682  int gid;
683  int uid;
684  String escaped_path;
685  String extension;
686  long seq;
687  long parMetaAddr;
688  long parSeq;
689 
690  FileInfo(long parentObjId,
691  long fsObjId, long dataSourceObjId,
692  int fsType,
693  int attrType, int attrId, String name,
694  long metaAddr, long metaSeq,
695  int dirType, int metaType, int dirFlags, int metaFlags,
696  long size,
697  long crtime, long ctime, long atime, long mtime,
698  int meta_mode, int gid, int uid,
699  String escaped_path, String extension,
700  long seq, long parMetaAddr, long parSeq) {
701 
702  this.parentObjId = parentObjId;
703  this.fsObjId = fsObjId;
704  this.dataSourceObjId = dataSourceObjId;
705  this.fsType = fsType;
706  this.attrType = attrType;
707  this.attrId = attrId;
708  this.name = name;
709  this.metaAddr = metaAddr;
710  this.metaSeq = metaSeq;
711  this.dirType = dirType;
712  this.metaType = metaType;
713  this.dirFlags = dirFlags;
714  this.metaFlags = metaFlags;
715  this.size = size;
716  this.crtime = crtime;
717  this.ctime = ctime;
718  this.atime = atime;
719  this.mtime = mtime;
720  this.meta_mode = meta_mode;
721  this.gid = gid;
722  this.uid = uid;
723  this.escaped_path = escaped_path;
724  this.extension = extension;
725  this.seq = seq;
726  this.parMetaAddr = parMetaAddr;
727  this.parSeq = parSeq;
728  }
729  }
730 
772  private long addFileToDb(long parentObjId,
773  Long fsObjId, long dataSourceObjId,
774  int fsType,
775  Integer attrType, Integer attrId, String name,
776  Long metaAddr, Long metaSeq,
777  int dirType, int metaType, int dirFlags, int metaFlags,
778  long size,
779  Long crtime, Long ctime, Long atime, Long mtime,
780  Integer meta_mode, Integer gid, Integer uid,
781  String md5, TskData.FileKnown known,
782  String escaped_path, String extension,
783  boolean hasLayout, CaseDbTransaction transaction) throws TskCoreException {
784 
785  try {
786  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
787 
788  // Insert a row for the local/logical file into the tsk_objects table.
789  // INSERT INTO tsk_objects (par_obj_id, type) VALUES (?, ?)
790  long objectId = caseDb.addObject(parentObjId, TskData.ObjectType.ABSTRACTFILE.getObjectType(), connection);
791 
792  String fileInsert = "INSERT INTO tsk_files (fs_obj_id, obj_id, data_source_obj_id, type, attr_type, attr_id, name, meta_addr, meta_seq, dir_type, meta_type, dir_flags, meta_flags, size, crtime, ctime, atime, mtime, mode, gid, uid, md5, known, parent_path, extension, has_layout)"
793  + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; // NON-NLS
794  PreparedStatement preparedStatement = connection.getPreparedStatement(fileInsert, Statement.NO_GENERATED_KEYS);
795  preparedStatement.clearParameters();
796 
797  if (fsObjId != null) {
798  preparedStatement.setLong(1, fsObjId); // fs_obj_id
799  } else {
800  preparedStatement.setNull(1, java.sql.Types.BIGINT);
801  }
802  preparedStatement.setLong(2, objectId); // obj_id
803  preparedStatement.setLong(3, dataSourceObjId); // data_source_obj_id
804  preparedStatement.setShort(4, (short) fsType); // type
805  if (attrType != null) {
806  preparedStatement.setShort(5, attrType.shortValue()); // attr_type
807  } else {
808  preparedStatement.setNull(5, java.sql.Types.SMALLINT);
809  }
810  if (attrId != null) {
811  preparedStatement.setInt(6, attrId); // attr_id
812  } else {
813  preparedStatement.setNull(6, java.sql.Types.INTEGER);
814  }
815  preparedStatement.setString(7, name); // name
816  if (metaAddr != null) {
817  preparedStatement.setLong(8, metaAddr); // meta_addr
818  } else {
819  preparedStatement.setNull(8, java.sql.Types.BIGINT);
820  }
821  if (metaSeq != null) {
822  preparedStatement.setInt(9, metaSeq.intValue()); // meta_seq
823  } else {
824  preparedStatement.setNull(9, java.sql.Types.INTEGER);
825  }
826  preparedStatement.setShort(10, (short) dirType); // dir_type
827  preparedStatement.setShort(11, (short) metaType); // meta_type
828  preparedStatement.setShort(12, (short) dirFlags); // dir_flags
829  preparedStatement.setShort(13, (short) metaFlags); // meta_flags
830  preparedStatement.setLong(14, size < 0 ? 0 : size); // size
831  if (crtime != null) {
832  preparedStatement.setLong(15, crtime); // crtime
833  } else {
834  preparedStatement.setNull(15, java.sql.Types.BIGINT);
835  }
836  if (ctime != null) {
837  preparedStatement.setLong(16, ctime); // ctime
838  } else {
839  preparedStatement.setNull(16, java.sql.Types.BIGINT);
840  }
841  if (atime != null) {
842  preparedStatement.setLong(17, atime); // atime
843  } else {
844  preparedStatement.setNull(17, java.sql.Types.BIGINT);
845  }
846  if (mtime != null) {
847  preparedStatement.setLong(18, mtime); // mtime
848  } else {
849  preparedStatement.setNull(18, java.sql.Types.BIGINT);
850  }
851  if (meta_mode != null) {
852  preparedStatement.setLong(19, meta_mode); // mode
853  } else {
854  preparedStatement.setNull(19, java.sql.Types.BIGINT);
855  }
856  if (gid != null) {
857  preparedStatement.setLong(20, gid); // gid
858  } else {
859  preparedStatement.setNull(20, java.sql.Types.BIGINT);
860  }
861  if (uid != null) {
862  preparedStatement.setLong(21, uid); // uid
863  } else {
864  preparedStatement.setNull(21, java.sql.Types.BIGINT);
865  }
866  preparedStatement.setString(22, md5); // md5
867  preparedStatement.setInt(23, known.getFileKnownValue());// known
868  preparedStatement.setString(24, escaped_path); // parent_path
869  preparedStatement.setString(25, extension); // extension
870  if (hasLayout) {
871  preparedStatement.setInt(26, 1); // has_layout
872  } else {
873  preparedStatement.setNull(26, java.sql.Types.INTEGER);
874  }
875  connection.executeUpdate(preparedStatement);
876 
877  // If this is not a slack file create the timeline events
878  if (!hasLayout
879  && TskData.TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType() != fsType
880  && (!name.equals(".")) && (!name.equals(".."))) {
881  TimelineManager timelineManager = caseDb.getTimelineManager();
882  DerivedFile derivedFile = new DerivedFile(caseDb, objectId, dataSourceObjId, name,
883  TskData.TSK_FS_NAME_TYPE_ENUM.valueOf((short) dirType),
884  TskData.TSK_FS_META_TYPE_ENUM.valueOf((short) metaType),
885  TskData.TSK_FS_NAME_FLAG_ENUM.valueOf(dirFlags),
886  (short) metaFlags,
887  size, ctime, crtime, atime, mtime, null, null, escaped_path, null, parentObjId, null, null, extension);
888 
889  timelineManager.addEventsForNewFileQuiet(derivedFile, connection);
890  }
891 
892  return objectId;
893  } catch (SQLException ex) {
894  throw new TskCoreException("Failed to add file system file", ex);
895  }
896  }
897 
916  private long addImageToDb(TskData.TSK_IMG_TYPE_ENUM type, long sectorSize, long size,
917  String timezone, String md5, String sha1, String sha256,
918  String deviceId, String collectionDetails,
919  CaseDbTransaction transaction) throws TskCoreException {
920  try {
921  // Insert a row for the Image into the tsk_objects table.
922  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
923  long newObjId = caseDb.addObject(0, TskData.ObjectType.IMG.getObjectType(), connection);
924 
925  // Add a row to tsk_image_info
926  // INSERT INTO tsk_image_info (obj_id, type, ssize, tzone, size, md5, sha1, sha256, display_name)
927  String imageInfoSql = "INSERT INTO tsk_image_info (obj_id, type, ssize, tzone, size, md5, sha1, sha256, display_name)"
928  + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)"; // NON-NLS
929  PreparedStatement preparedStatement = connection.getPreparedStatement(imageInfoSql, Statement.NO_GENERATED_KEYS);
930  preparedStatement.clearParameters();
931  preparedStatement.setLong(1, newObjId);
932  preparedStatement.setShort(2, (short) type.getValue());
933  preparedStatement.setLong(3, sectorSize);
934  preparedStatement.setString(4, timezone);
935  //prevent negative size
936  long savedSize = size < 0 ? 0 : size;
937  preparedStatement.setLong(5, savedSize);
938  preparedStatement.setString(6, md5);
939  preparedStatement.setString(7, sha1);
940  preparedStatement.setString(8, sha256);
941  preparedStatement.setString(9, null);
942  connection.executeUpdate(preparedStatement);
943 
944  // Add a row to data_source_info
945  String dataSourceInfoSql = "INSERT INTO data_source_info (obj_id, device_id, time_zone, acquisition_details) VALUES (?, ?, ?, ?)"; // NON-NLS
946  preparedStatement = connection.getPreparedStatement(dataSourceInfoSql, Statement.NO_GENERATED_KEYS);
947  preparedStatement.clearParameters();
948  preparedStatement.setLong(1, newObjId);
949  preparedStatement.setString(2, deviceId);
950  preparedStatement.setString(3, timezone);
951  preparedStatement.setString(4, collectionDetails);
952  connection.executeUpdate(preparedStatement);
953 
954  return newObjId;
955  } catch (SQLException ex) {
956  throw new TskCoreException(String.format("Error adding image to database"), ex);
957  }
958  }
959 
970  private void addImageNameToDb(long objId, String name, long sequence,
971  CaseDbTransaction transaction) throws TskCoreException {
972  try {
973  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
974 
975  String imageNameSql = "INSERT INTO tsk_image_names (obj_id, name, sequence) VALUES (?, ?, ?)"; // NON-NLS
976  PreparedStatement preparedStatement = connection.getPreparedStatement(imageNameSql, Statement.NO_GENERATED_KEYS);
977  preparedStatement.clearParameters();
978  preparedStatement.setLong(1, objId);
979  preparedStatement.setString(2, name);
980  preparedStatement.setLong(3, sequence);
981  connection.executeUpdate(preparedStatement);
982  } catch (SQLException ex) {
983  throw new TskCoreException(String.format("Error adding image name %s to image with object ID %d", name, objId), ex);
984  }
985  }
986 
998  void addLayoutFileRangeToDb(long objId, long byteStart, long byteLen,
999  long seq, CaseDbTransaction transaction) throws TskCoreException {
1000  try {
1001  SleuthkitCase.CaseDbConnection connection = transaction.getConnection();
1002 
1003  String insertRangeSql = "INSERT INTO tsk_file_layout (obj_id, byte_start, byte_len, sequence) " //NON-NLS
1004  + "VALUES (?, ?, ?, ?)";
1005  PreparedStatement preparedStatement = connection.getPreparedStatement(insertRangeSql, Statement.NO_GENERATED_KEYS);
1006  preparedStatement.clearParameters();
1007  preparedStatement.setLong(1, objId);
1008  preparedStatement.setLong(2, byteStart);
1009  preparedStatement.setLong(3, byteLen);
1010  preparedStatement.setLong(4, seq);
1011  connection.executeUpdate(preparedStatement);
1012  } catch (SQLException ex) {
1013  throw new TskCoreException("Error adding layout range to file with obj ID " + objId, ex);
1014  }
1015  }
1016 }

Copyright © 2011-2020 Brian Carrier. (carrier -at- sleuthkit -dot- org)
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.