diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/StartupWindow.java b/Core/src/org/sleuthkit/autopsy/casemodule/StartupWindow.java
index 8b94b0d441..d15a8aa915 100644
--- a/Core/src/org/sleuthkit/autopsy/casemodule/StartupWindow.java
+++ b/Core/src/org/sleuthkit/autopsy/casemodule/StartupWindow.java
@@ -43,6 +43,7 @@ public final class StartupWindow extends JDialog implements StartupWindowInterfa
}
private void init() {
+
setSize(DIMENSIONS);
welcomeWindow = new CueBannerPanel();
welcomeWindow.setCloseButtonActionListener(new ActionListener() {
@@ -58,7 +59,9 @@ public final class StartupWindow extends JDialog implements StartupWindowInterfa
@Override
public void open() {
- welcomeWindow.refresh();
+ if (welcomeWindow != null) {
+ welcomeWindow.refresh();
+ }
setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
setVisible(true);
}
diff --git a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java
index 6bd42367e2..4adae57b8d 100644
--- a/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java
+++ b/Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java
@@ -138,7 +138,8 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
"Metadata.tableRowTitle.timezone=Time Zone",
"Metadata.tableRowTitle.deviceId=Device ID",
"Metadata.tableRowTitle.acquisitionDetails=Acquisition Details",
- "Metadata.nodeText.unknown=Unknown"})
+ "Metadata.nodeText.unknown=Unknown",
+ "Metadata.nodeText.none=None"})
@Override
public void setNode(Node node) {
AbstractFile file = node.getLookup().lookup(AbstractFile.class);
@@ -251,15 +252,20 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
// Add all the data source paths to the "Local Path" value cell.
String[] imagePaths = image.getPaths();
- StringBuilder pathValues = new StringBuilder("
");
- pathValues.append(imagePaths[0]);
- pathValues.append("
");
- for (int i=1; i < imagePaths.length; i++) {
- pathValues.append("");
- pathValues.append(imagePaths[i]);
+ if (imagePaths.length > 0) {
+ StringBuilder pathValues = new StringBuilder("
");
+ pathValues.append(imagePaths[0]);
pathValues.append("
");
+ for (int i=1; i < imagePaths.length; i++) {
+ pathValues.append("
");
+ pathValues.append(imagePaths[i]);
+ pathValues.append("
");
+ }
+ addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), pathValues.toString());
+ } else {
+ addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"),
+ NbBundle.getMessage(this.getClass(), "Metadata.nodeText.none"));
}
- addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), pathValues.toString());
}
setText(sb.toString());
diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java
index 82c7df497a..601d74293d 100644
--- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java
+++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerHex.java
@@ -31,8 +31,10 @@ import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
+import javax.swing.SwingWorker;
import javax.swing.text.BadLocationException;
import javax.swing.text.Utilities;
+import org.netbeans.api.progress.ProgressHandle;
import org.openide.nodes.Node;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.casemodule.Case;
@@ -359,36 +361,71 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
}//GEN-LAST:event_goToOffsetTextFieldActionPerformed
@NbBundle.Messages({"DataContentViewerHex.launchError=Unable to launch HxD Editor. "
- + "Please set-up the HdX install location in Tools -> Options -> External Viewer"})
+ + "Please specify the HxD install location in Tools -> Options -> External Viewer",
+ "DataContentViewerHex.copyingFile=Copying file to open in HxD..."})
private void launchHxDButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_launchHxDButtonActionPerformed
- try {
- File HdXExecutable = new File(UserPreferences.getExternalHexEditorPath());
- if(!HdXExecutable.exists() || !HdXExecutable.canExecute()) {
- JOptionPane.showMessageDialog(null, DataContentViewerHex_launchError());
- return;
- }
-
- String tempDirectory = Case.getCurrentCaseThrows().getTempDirectory();
- File dataSourceInTempDirectory = Paths.get(tempDirectory,
- FileUtil.escapeFileName(dataSource.getId() + dataSource.getName())).toFile();
- ContentUtils.writeToFile(dataSource, dataSourceInTempDirectory);
-
- try {
- ProcessBuilder launchHdXExecutable = new ProcessBuilder();
- launchHdXExecutable.command(String.format("\"%s\" \"%s\"",
- HdXExecutable.getAbsolutePath(),
- dataSourceInTempDirectory.getAbsolutePath()));
- launchHdXExecutable.start();
- } catch (IOException ex) {
- JOptionPane.showMessageDialog(null, DataContentViewerHex_launchError());
- dataSourceInTempDirectory.delete();
- }
- } catch (NoCurrentCaseException | IOException ex) {
- logger.log(Level.SEVERE, "Unable to copy file into temp directory", ex);
- JOptionPane.showMessageDialog(null, DataContentViewerHex_launchError());
- }
+ new BackgroundFileCopyTask().execute();
}//GEN-LAST:event_launchHxDButtonActionPerformed
+ /**
+ * Performs the file copying and process launching in a SwingWorker so that the
+ * UI is not blocked when opening large files.
+ */
+ private class BackgroundFileCopyTask extends SwingWorker
{
+ private boolean wasCancelled = false;
+
+ @Override
+ public Void doInBackground() throws InterruptedException {
+ ProgressHandle progress = ProgressHandle.createHandle(DataContentViewerHex_copyingFile(), () -> {
+ //Cancel the swing worker (which will interrupt the ContentUtils call below)
+ this.cancel(true);
+ wasCancelled = true;
+ return true;
+ });
+
+ try {
+ File HxDExecutable = new File(UserPreferences.getExternalHexEditorPath());
+ if(!HxDExecutable.exists() || !HxDExecutable.canExecute()) {
+ JOptionPane.showMessageDialog(null, DataContentViewerHex_launchError());
+ return null;
+ }
+
+ String tempDirectory = Case.getCurrentCaseThrows().getTempDirectory();
+ File tempFile = Paths.get(tempDirectory,
+ FileUtil.escapeFileName(dataSource.getId() + dataSource.getName())).toFile();
+
+ progress.start(100);
+ ContentUtils.writeToFile(dataSource, tempFile, progress, this, true);
+
+ if(wasCancelled) {
+ tempFile.delete();
+ progress.finish();
+ return null;
+ }
+
+ try {
+ ProcessBuilder launchHxDExecutable = new ProcessBuilder();
+ launchHxDExecutable.command(String.format("\"%s\" \"%s\"",
+ HxDExecutable.getAbsolutePath(),
+ tempFile.getAbsolutePath()));
+ launchHxDExecutable.start();
+ } catch (IOException ex) {
+ logger.log(Level.WARNING, "Unsuccessful attempt to launch HxD", ex);
+ JOptionPane.showMessageDialog(null, DataContentViewerHex_launchError());
+ tempFile.delete();
+ }
+ } catch (NoCurrentCaseException | IOException ex) {
+ logger.log(Level.SEVERE, "Unable to copy file into temp directory", ex);
+ JOptionPane.showMessageDialog(null, DataContentViewerHex_launchError());
+ }
+
+ progress.finish();
+ return null;
+ }
+ }
+
+
+
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JMenuItem copyMenuItem;
private javax.swing.JLabel currentPageLabel;
diff --git a/Core/src/org/sleuthkit/autopsy/coreutils/NetworkUtils.java b/Core/src/org/sleuthkit/autopsy/coreutils/NetworkUtils.java
index 78547f8370..42266745f2 100644
--- a/Core/src/org/sleuthkit/autopsy/coreutils/NetworkUtils.java
+++ b/Core/src/org/sleuthkit/autopsy/coreutils/NetworkUtils.java
@@ -92,6 +92,12 @@ public class NetworkUtils {
if (base.matches(".*[~`!@#$%^&\\*\\(\\)\\+={}\\[\\];:\\?<>,/ ].*")) {
return "";
}
+
+ //verify that the base domain actually has a '.', details JIRA-4609
+ if(!base.contains(".")) {
+ return "";
+ }
+
return base;
}
diff --git a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/MSOfficeEmbeddedContentExtractor.java b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/MSOfficeEmbeddedContentExtractor.java
index e7e959e175..16c2b0e3e8 100644
--- a/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/MSOfficeEmbeddedContentExtractor.java
+++ b/Core/src/org/sleuthkit/autopsy/modules/embeddedfileextractor/MSOfficeEmbeddedContentExtractor.java
@@ -516,8 +516,7 @@ class MSOfficeEmbeddedContentExtractor {
* @return
*/
private String getFileRelativePath(String fileName) {
- // Used explicit FWD slashes to maintain DB consistency across operating systems.
- return "/" + moduleDirRelative + "/" + this.parentFileName + "/" + fileName; //NON-NLS
+ return Paths.get(moduleDirRelative, this.parentFileName, fileName).toString();
}
/**
diff --git a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java
index 8c225381df..dace794e85 100644
--- a/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java
+++ b/Core/src/org/sleuthkit/autopsy/modules/filetypeid/FileTypeDetector.java
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
+import java.util.logging.Level;
import java.util.stream.Collectors;
import org.apache.tika.Tika;
import org.apache.tika.io.TikaInputStream;
@@ -57,7 +58,7 @@ public class FileTypeDetector {
* @return A list of all detectable file types.
*
* @throws FileTypeDetectorInitException If an error occurs while assembling
- * the list of types
+ * the list of types
*/
public static synchronized SortedSet getDetectedTypes() throws FileTypeDetectorInitException {
TreeSet detectedTypes = new TreeSet<>((String string1, String string2) -> {
@@ -108,9 +109,7 @@ public class FileTypeDetector {
* Tika, and Autopsy file type definitions take precendence over Tika.
*
* @throws FileTypeDetectorInitException If an initialization error occurs,
- * e.g., user-defined file type
- * definitions exist but cannot be
- * loaded.
+ * e.g., user-defined file type definitions exist but cannot be loaded.
*/
public FileTypeDetector() throws FileTypeDetectorInitException {
try {
@@ -140,7 +139,7 @@ public class FileTypeDetector {
* user-defined MIME type by this detector.
*
* @param customTypes
- * @param mimeType The MIME type name (e.g., "text/html").
+ * @param mimeType The MIME type name (e.g., "text/html").
*
* @return True or false.
*/
@@ -171,9 +170,9 @@ public class FileTypeDetector {
* @param file The file to test.
*
* @return A MIME type name. If file type could not be detected, or results
- * were uncertain, octet-stream is returned.
- *
-
+ * were uncertain, octet-stream is returned.
+ *
+ *
*/
public String getMIMEType(AbstractFile file) {
/*
@@ -235,6 +234,22 @@ public class FileTypeDetector {
*/
mimeType = removeOptionalParameter(mimeType);
+ /**
+ * We cannot trust Tika's audio/mpeg mimetype. Lets verify the
+ * first two bytes and confirm it is not 0xffff. Details in
+ * JIRA-4659
+ */
+ if (mimeType.contains("audio/mpeg")) {
+ try {
+ byte[] header = getNBytes(file, 0, 2);
+ if (byteIs0xFF(header[0]) && byteIs0xFF(header[1])) {
+ mimeType = MimeTypes.OCTET_STREAM;
+ }
+ } catch (TskCoreException ex) {
+ //Oh well, the mimetype is what it is.
+ logger.log(Level.WARNING, String.format("Could not verify audio/mpeg mimetype for file %s with id=%d", file.getName(), file.getId()), ex);
+ }
+ }
} catch (Exception ignored) {
/*
* This exception is swallowed and not logged rather than
@@ -255,6 +270,33 @@ public class FileTypeDetector {
return mimeType;
}
+ /**
+ * Determine if the byte is 255 (0xFF) by examining the last 4 bits and the
+ * first 4 bits.
+ *
+ * @param x byte
+ * @return Flag indicating the byte if 0xFF
+ */
+ private boolean byteIs0xFF(byte x) {
+ return (x & 0x0F) == 0x0F && (x & 0xF0) == 0xF0;
+ }
+
+ /**
+ * Retrieves the first N bytes from a file.
+ *
+ * @param file Abstract file to read
+ * @param offset Offset to begin reading
+ * @param n Number of bytes to read
+ * @return Byte array of size n
+ *
+ * @throws TskCoreException
+ */
+ private byte[] getNBytes(AbstractFile file, int offset, int n) throws TskCoreException {
+ byte[] headerCache = new byte[n];
+ file.read(headerCache, offset, n);
+ return headerCache;
+ }
+
/**
* Removes the optional parameter from a MIME type string
*
@@ -280,7 +322,7 @@ public class FileTypeDetector {
*/
private String detectUserDefinedType(AbstractFile file) {
String retValue = null;
-
+
for (FileType fileType : userDefinedFileTypes) {
if (fileType.matches(file)) {
retValue = fileType.getMimeType();
@@ -291,7 +333,8 @@ public class FileTypeDetector {
}
/**
- * Determines whether or not a file matches a custom file type defined by Autopsy.
+ * Determines whether or not a file matches a custom file type defined by
+ * Autopsy.
*
* @param file The file to test.
*
@@ -328,7 +371,7 @@ public class FileTypeDetector {
* Constructs an exception to throw if an initialization error occurs,
* e.g., user-defined file type definitions exist but cannot be loaded.
*
- * @param message The exception message,
+ * @param message The exception message,
* @param throwable The underlying cause of the exception.
*/
FileTypeDetectorInitException(String message, Throwable throwable) {
@@ -366,7 +409,7 @@ public class FileTypeDetector {
* @return A MIME type name.
*
* @throws TskCoreException if detection is required and there is a problem
- * writing the result to the case database.
+ * writing the result to the case database.
* @deprecated Use getMIMEType instead, and call AbstractFile.setMIMEType
* and AbstractFile.save to save the result to the file object and the
* database.
@@ -386,10 +429,10 @@ public class FileTypeDetector {
* @param file The file.
*
* @return A MIME type name. If file type could not be detected or results
- * were uncertain, octet-stream is returned.
+ * were uncertain, octet-stream is returned.
*
* @throws TskCoreException if detection is required and there is a problem
- * writing the result to the case database.
+ * writing the result to the case database.
*
* @deprecated Use getMIMEType instead, and call AbstractFile.setMIMEType
* and AbstractFile.save to save the result to the file object and the
@@ -410,7 +453,7 @@ public class FileTypeDetector {
* @param file The file to test.
*
* @return A MIME type name. If file type could not be detected or results
- * were uncertain, octet-stream is returned.
+ * were uncertain, octet-stream is returned.
*
* @throws TskCoreException
* @deprecated Use getMIMEType instead.
diff --git a/Core/src/org/sleuthkit/autopsy/textextractors/TikaTextExtractor.java b/Core/src/org/sleuthkit/autopsy/textextractors/TikaTextExtractor.java
index 0a05a238c4..9491e75783 100644
--- a/Core/src/org/sleuthkit/autopsy/textextractors/TikaTextExtractor.java
+++ b/Core/src/org/sleuthkit/autopsy/textextractors/TikaTextExtractor.java
@@ -50,6 +50,7 @@ import org.apache.tika.parser.ParsingReader;
import org.apache.tika.parser.microsoft.OfficeParserConfig;
import org.apache.tika.parser.ocr.TesseractOCRConfig;
import org.apache.tika.parser.pdf.PDFParserConfig;
+import org.apache.tika.mime.MediaType;
import org.openide.util.NbBundle;
import org.openide.modules.InstalledFileLocator;
import org.openide.util.Lookup;
@@ -125,7 +126,7 @@ final class TikaTextExtractor implements TextExtractor {
private final ExecutorService executorService = Executors.newSingleThreadExecutor(tikaThreadFactory);
private static final String SQLITE_MIMETYPE = "application/x-sqlite3";
- private final AutoDetectParser parser = new AutoDetectParser();
+ private final AutoDetectParser parser;
private final Content content;
private boolean tesseractOCREnabled;
@@ -134,7 +135,7 @@ final class TikaTextExtractor implements TextExtractor {
private static final File TESSERACT_PATH = locateTesseractExecutable();
private String languagePacks = formatLanguagePacks(PlatformUtil.getOcrLanguagePacks());
private static final String TESSERACT_OUTPUT_FILE_NAME = "tess_output"; //NON-NLS
-
+
private ProcessTerminator processTerminator;
private static final List TIKA_SUPPORTED_TYPES
@@ -145,12 +146,23 @@ final class TikaTextExtractor implements TextExtractor {
public TikaTextExtractor(Content content) {
this.content = content;
+
+ parser = new AutoDetectParser();
+
+ if (content instanceof AbstractFile) {
+ AbstractFile file = (AbstractFile) content;
+ if (file.getMIMEType() != null && !file.getMIMEType().isEmpty()) {
+ //Force Tika to use our pre-computed mime type during detection
+ parser.setDetector((InputStream inStream, Metadata metaData)
+ -> MediaType.parse(file.getMIMEType()));
+ }
+ }
}
/**
* If Tesseract has been installed and is set to be used through
- * configuration, then ocr is enabled. OCR can only currently be run on
- * 64 bit Windows OS.
+ * configuration, then ocr is enabled. OCR can only currently be run on 64
+ * bit Windows OS.
*
* @return Flag indicating if OCR is set to be used.
*/
@@ -199,7 +211,7 @@ final class TikaTextExtractor implements TextExtractor {
TesseractOCRConfig ocrConfig = new TesseractOCRConfig();
String tesseractFolder = TESSERACT_PATH.getParent();
ocrConfig.setTesseractPath(tesseractFolder);
-
+
ocrConfig.setLanguage(languagePacks);
ocrConfig.setTessdataPath(PlatformUtil.getOcrLanguagePacksPath());
parseContext.set(TesseractOCRConfig.class, ocrConfig);
@@ -269,7 +281,7 @@ final class TikaTextExtractor implements TextExtractor {
File outputFile = null;
try {
String tempDirectory = Case.getCurrentCaseThrows().getTempDirectory();
-
+
//Appending file id makes the name unique
String tempFileName = FileUtil.escapeFileName(file.getId() + file.getName());
inputFile = Paths.get(tempDirectory, tempFileName).toFile();
@@ -310,7 +322,7 @@ final class TikaTextExtractor implements TextExtractor {
}
}
}
-
+
/**
* Wraps the creation of a TikaReader into a Future so that it can be
* cancelled.
@@ -422,11 +434,11 @@ final class TikaTextExtractor implements TextExtractor {
*/
@Override
public boolean isSupported() {
- if(!(content instanceof AbstractFile)) {
+ if (!(content instanceof AbstractFile)) {
return false;
}
-
- String detectedType = ((AbstractFile)content).getMIMEType();
+
+ String detectedType = ((AbstractFile) content).getMIMEType();
if (detectedType == null
|| BINARY_MIME_TYPES.contains(detectedType) //any binary unstructured blobs (string extraction will be used)
|| ARCHIVE_MIME_TYPES.contains(detectedType)
@@ -435,7 +447,7 @@ final class TikaTextExtractor implements TextExtractor {
) {
return false;
}
-
+
return TIKA_SUPPORTED_TYPES.contains(detectedType);
}
@@ -485,11 +497,11 @@ final class TikaTextExtractor implements TextExtractor {
if (context != null) {
ImageConfig configInstance = context.lookup(ImageConfig.class);
if (configInstance != null) {
- if(Objects.nonNull(configInstance.getOCREnabled())) {
+ if (Objects.nonNull(configInstance.getOCREnabled())) {
this.tesseractOCREnabled = configInstance.getOCREnabled();
}
-
- if(Objects.nonNull(configInstance.getOCRLanguages())) {
+
+ if (Objects.nonNull(configInstance.getOCRLanguages())) {
this.languagePacks = formatLanguagePacks(configInstance.getOCRLanguages());
}
}
diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/IngestJobRunningService.java b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/IngestJobRunningService.java
new file mode 100755
index 0000000000..67fe15136a
--- /dev/null
+++ b/Experimental/src/org/sleuthkit/autopsy/experimental/configuration/IngestJobRunningService.java
@@ -0,0 +1,44 @@
+/*
+ * Autopsy Forensic Browser
+ *
+ * Copyright 2011-2018 Basis Technology Corp.
+ * Contact: carrier sleuthkit org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.experimental.configuration;
+
+import javax.swing.JPanel;
+
+/**
+ * Interface to run an ingest job in the background.
+ */
+public interface IngestJobRunningService {
+
+ /**
+ * Starts the service
+ */
+ void start();
+
+ /**
+ * Stops the service
+ */
+ void stop();
+
+ /**
+ * Returns a panel to be displayed while using this service
+ *
+ * @return panel to be displayed while using this service
+ */
+ JPanel getStartupWindow();
+}
diff --git a/test/script/tskdbdiff.py b/test/script/tskdbdiff.py
index 54b48a1987..d33b40686a 100644
--- a/test/script/tskdbdiff.py
+++ b/test/script/tskdbdiff.py
@@ -320,7 +320,8 @@ class TskDbDiff(object):
id_objects_table = build_id_objects_table(conn.cursor(), isMultiUser)
id_artifact_types_table = build_id_artifact_types_table(conn.cursor(), isMultiUser)
id_reports_table = build_id_reports_table(conn.cursor(), isMultiUser)
- id_obj_path_table = build_id_obj_path_table(id_files_table, id_objects_table, id_artifact_types_table, id_reports_table)
+ id_images_table = build_id_image_names_table(conn.cursor(), isMultiUser)
+ id_obj_path_table = build_id_obj_path_table(id_files_table, id_objects_table, id_artifact_types_table, id_reports_table, id_images_table)
if isMultiUser: # Use PostgreSQL
os.environ['PGPASSWORD']=pgSettings.password
@@ -333,14 +334,17 @@ class TskDbDiff(object):
for line in postgreSQL_db:
line = line.strip('\r\n ')
# Deal with pg_dump result file
- if (line.startswith('--') or line.lower().startswith('alter') or "pg_catalog" in line or "idle_in_transaction_session_timeout" in line or not line or 'INSERT INTO "image_gallery_groups_seen"' in line): # It's comment or alter statement or catalog entry or set idle entry or empty line
+ if (line.startswith('--') or line.lower().startswith('alter') or "pg_catalog" in line or "idle_in_transaction_session_timeout" in line or not line): # It's comment or alter statement or catalog entry or set idle entry or empty line
continue
elif not line.endswith(';'): # Statement not finished
dump_line += line
continue
else:
dump_line += line
- dump_line = normalize_db_entry(dump_line, id_obj_path_table, id_vs_parts_table, id_vs_info_table, id_fs_info_table, id_objects_table, id_reports_table)
+ if 'INSERT INTO image_gallery_groups_seen' in dump_line:
+ dump_line = ''
+ continue;
+ dump_line = normalize_db_entry(dump_line, id_obj_path_table, id_vs_parts_table, id_vs_info_table, id_fs_info_table, id_objects_table, id_reports_table, id_images_table)
db_log.write('%s\n' % dump_line)
dump_line = ''
postgreSQL_db.close()
@@ -354,7 +358,7 @@ class TskDbDiff(object):
for line in conn.iterdump():
if 'INSERT INTO "image_gallery_groups_seen"' in line:
continue
- line = normalize_db_entry(line, id_obj_path_table, id_vs_parts_table, id_vs_info_table, id_fs_info_table, id_objects_table, id_reports_table)
+ line = normalize_db_entry(line, id_obj_path_table, id_vs_parts_table, id_vs_info_table, id_fs_info_table, id_objects_table, id_reports_table, id_images_table)
db_log.write('%s\n' % line)
# Now sort the file
srtcmdlst = ["sort", dump_file, "-o", dump_file]
@@ -406,7 +410,7 @@ class PGSettings(object):
return self.password
-def normalize_db_entry(line, files_table, vs_parts_table, vs_info_table, fs_info_table, objects_table, reports_table):
+def normalize_db_entry(line, files_table, vs_parts_table, vs_info_table, fs_info_table, objects_table, reports_table, images_table):
""" Make testing more consistent and reasonable by doctoring certain db entries.
Args:
@@ -515,6 +519,8 @@ def normalize_db_entry(line, files_table, vs_parts_table, vs_info_table, fs_info
parent_path = vs_info_table[parent_id]
elif parent_id in fs_info_table.keys():
parent_path = fs_info_table[parent_id]
+ elif parent_id in images_table.keys():
+ parent_path = images_table[parent_id]
elif parent_id == 'NULL':
parent_path = "NULL"
@@ -620,6 +626,18 @@ def build_id_objects_table(db_cursor, isPostgreSQL):
mapping = dict([(row[0], [row[1], row[2]]) for row in sql_select_execute(db_cursor, isPostgreSQL, "SELECT * FROM tsk_objects")])
return mapping
+def build_id_image_names_table(db_cursor, isPostgreSQL):
+ """Build the map of object ids to name.
+
+ Args:
+ db_cursor: the database cursor
+ """
+ # for each row in the db, take the object id and name then create a tuple in the dictionary
+ # with the object id as the key and name, type as the value
+ mapping = dict([(row[0], row[1]) for row in sql_select_execute(db_cursor, isPostgreSQL, "SELECT obj_id, name FROM tsk_image_names WHERE sequence=0")])
+ #data_sources which are logical file sets will be found in the files table
+ return mapping
+
def build_id_artifact_types_table(db_cursor, isPostgreSQL):
"""Build the map of object ids to artifact ids.
@@ -642,7 +660,7 @@ def build_id_reports_table(db_cursor, isPostgreSQL):
return mapping
-def build_id_obj_path_table(files_table, objects_table, artifacts_table, reports_table):
+def build_id_obj_path_table(files_table, objects_table, artifacts_table, reports_table, images_table):
"""Build the map of object ids to artifact ids.
Args:
@@ -654,6 +672,7 @@ def build_id_obj_path_table(files_table, objects_table, artifacts_table, reports
# make a copy of files_table and update it with new data from artifacts_table and reports_table
mapping = files_table.copy()
for k, v in objects_table.items():
+ path = ""
if k not in mapping.keys(): # If the mapping table doesn't have data for obj_id
if k in reports_table.keys(): # For a report we use the report path
par_obj_id = v[0]
@@ -665,6 +684,8 @@ def build_id_obj_path_table(files_table, objects_table, artifacts_table, reports
path = mapping[par_obj_id]
elif par_obj_id in reports_table.keys():
path = reports_table[par_obj_id]
+ elif par_obj_id in images_table.keys():
+ path = images_table[par_obj_id]
mapping[k] = path + "/" + artifacts_table[k]
elif v[0] not in mapping.keys():
if v[0] in artifacts_table.keys():