diff --git a/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java b/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java index 05f773a784..9d7c3973ed 100644 --- a/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java +++ b/DataModel/src/org/sleuthkit/autopsy/datamodel/BlackboardArtifactNode.java @@ -145,8 +145,6 @@ public class BlackboardArtifactNode extends AbstractNode implements DisplayableI private static Content getAssociatedContent(BlackboardArtifact artifact){ try { return artifact.getSleuthkitCase().getContentById(artifact.getObjectID()); - } catch (SQLException ex) { - logger.log(Level.WARNING, "SQL query threw exception", ex); } catch (TskException ex) { logger.log(Level.WARNING, "Getting file failed", ex); } diff --git a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbIngestService.java b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbIngestService.java index 35be0170b4..fffb10a3ca 100644 --- a/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbIngestService.java +++ b/HashDatabase/src/org/sleuthkit/autopsy/hashdatabase/HashDbIngestService.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.hashdatabase; +import java.beans.PropertyChangeListener; import java.io.IOException; import java.sql.SQLException; import java.util.Collections; @@ -185,9 +186,6 @@ public class HashDbIngestService implements IngestServiceFsContent { // TODO: This shouldn't be at level INFO, but it needs to be to hide the popup logger.log(Level.INFO, "Couldn't analyze file " + name + " - see sleuthkit log for details", ex); ret = ProcessResult.ERROR; - } catch (SQLException ex) { - logger.log(Level.WARNING, "Error updating file known status in database", ex); - ret = ProcessResult.ERROR; } catch (IOException ex) { // TODO: This shouldn't be at level INFO, but it needs to be to hide the popup logger.log(Level.INFO, "Error reading file", ex); @@ -207,6 +205,11 @@ public class HashDbIngestService implements IngestServiceFsContent { return false; } + @Override + public boolean backgroundJobsCompleteListener(PropertyChangeListener l) { + return false; + } + @Override public boolean hasSimpleConfiguration() { return false; diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java index d1b837b729..bf497be095 100755 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestManager.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.ingest; +import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.text.DateFormat; @@ -139,7 +140,7 @@ public class IngestManager { * @param images images to execute services on */ void execute(final List services, final List images) { - logger.log(Level.INFO, "Will enqueue number of images: " + images.size()); + logger.log(Level.INFO, "Will enqueue number of images: " + images.size() + " to " + services.size() + " services."); if (!isIngestRunning()) { ui.clearMessages(); @@ -443,8 +444,9 @@ public class IngestManager { */ public static List enumerateImageServices() { List ret = new ArrayList(); - for (IngestServiceImage list : Lookup.getDefault().lookupAll(IngestServiceImage.class)) + for (IngestServiceImage list : Lookup.getDefault().lookupAll(IngestServiceImage.class)) { ret.add(list); + } return ret; } @@ -453,8 +455,9 @@ public class IngestManager { */ public static List enumerateFsContentServices() { List ret = new ArrayList(); - for (IngestServiceFsContent list : Lookup.getDefault().lookupAll(IngestServiceFsContent.class)) + for (IngestServiceFsContent list : Lookup.getDefault().lookupAll(IngestServiceFsContent.class)) { ret.add(list); + } return ret; } @@ -750,7 +753,7 @@ public class IngestManager { public synchronized String toString() { return "FsContentQueue, size: " + Integer.toString(fsContentUnits.size()); } - + public String printQueue() { StringBuilder sb = new StringBuilder(); for (QueueUnit u : fsContentUnits) { @@ -903,7 +906,7 @@ public class IngestManager { hash = 37 * hash + (this.services != null ? this.services.hashCode() : 0); return hash; } - + @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -957,14 +960,10 @@ public class IngestManager { public String toHtmlString() { StringBuilder sb = new StringBuilder(); sb.append(""); - if (startTime != null) { - sb.append("Start time: ").append(dateFormatter.format(startTime)).append("
"); - } - if (endTime != null) { - sb.append("End time: ").append(dateFormatter.format(endTime)).append("
"); - } - sb.append("Total ingest time: ").append(getTotalTimeString()).append("
"); + + sb.append("Ingest time: ").append(getTotalTimeString()).append("
"); sb.append("Total errors: ").append(errorsTotal).append("
"); + /* if (errorsTotal > 0) { sb.append("Errors per service:"); for (IngestServiceAbstract service : errors.keySet()) { @@ -972,6 +971,8 @@ public class IngestManager { sb.append("\t").append(service.getName()).append(": ").append(errorsService).append("
"); } } + * */ + sb.append(""); return sb.toString(); } @@ -1134,18 +1135,63 @@ public class IngestManager { handleInterruption(); logger.log(Level.SEVERE, "Fatal error during ingest.", ex); } finally { - stats.end(); + //stats.end(); progress.finish(); if (!this.isCancelled()) { - logger.log(Level.INFO, "Summary Report: " + stats.toString()); - ui.displayReport(stats.toHtmlString()); + //logger.log(Level.INFO, "Summary Report: " + stats.toString()); + //ui.displayReport(stats.toHtmlString()); + new FsServicesComplete(stats); } initMainProgress(0); } } + /** + * Ensures that all background threads are done + * then finalize the stats and show dialog + */ + private class FsServicesComplete { + + private IngestManagerStats stats; //ongoing stats + private List running = new ArrayList(); + + FsServicesComplete(IngestManagerStats stats) { + this.stats = stats; + + for (IngestServiceAbstract s : fsContentServices) { + if (s.backgroundJobsCompleteListener(new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + if (evt.getPropertyName().equals(IngestServiceAbstract.BCKGRND_JOBS_COMPLETED_EVT)) { + IngestServiceAbstract service = (IngestServiceAbstract) evt.getNewValue(); + running.remove(service); + if (running.isEmpty()) { + showStats(); + } + } + } + })) { + running.add(s); + } + } + + //no listeners registered since no services running any longer + if (running.isEmpty()) { + showStats(); + } + + } + + void showStats() { + stats.end(); + logger.log(Level.INFO, "Summary Report: " + stats.toString()); + ui.displayReport(stats.toHtmlString()); + } + } + private void handleInterruption() { for (IngestServiceFsContent s : fsContentServices) { s.stop(); @@ -1254,9 +1300,9 @@ public class IngestManager { progress.progress(serviceName + " " + imageName, ++processed); } } - + //logger.log(Level.INFO, fsContentQueue.printQueue()); - + progress.progress("Sorting files", processed); sortFsContents(); } diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessagePanel.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessagePanel.java index 64792b8723..b53fe8da17 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessagePanel.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessagePanel.java @@ -555,7 +555,7 @@ class IngestMessagePanel extends javax.swing.JPanel { static Color VERY_HIGH_PRI_COLOR = new Color(164, 164, 202); //for a single message in a group static Color HIGH_PRI_COLOR = new Color(180, 180, 211); - static Color MED_PRI_COLOR = new Color(199, 199, 202); + static Color MED_PRI_COLOR = new Color(199, 199, 222); static Color LOW_PRI_COLOR = new Color(221, 221, 235); private List messages; private int count; diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.java index bb6f3213e1..192ecdcf6d 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestMessageTopComponent.java @@ -20,13 +20,15 @@ package org.sleuthkit.autopsy.ingest; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.Action; import javax.swing.BoxLayout; import javax.swing.JOptionPane; import org.openide.util.ImageUtilities; import org.openide.util.NbBundle; +import org.openide.util.Utilities; import org.openide.windows.Mode; import org.openide.windows.TopComponent; import org.openide.windows.WindowManager; @@ -103,22 +105,22 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing if (manager == null) { manager = IngestManager.getDefault(); } - + } @Override public void componentClosed() { //logger.log(Level.INFO, "CLOSED"); super.componentClosed(); - + /* Mode mode = WindowManager.getDefault().findMode("dockedBottom"); if (mode != null) { - mode.dockInto(this); - this.open(); + mode.dockInto(this); + this.open(); } * */ - + //this.close(); } @@ -126,7 +128,7 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing protected void componentShowing() { //logger.log(Level.INFO, "SHOWING"); super.componentShowing(); - + Mode mode = WindowManager.getDefault().findMode("floatingLeftBottom"); if (mode != null) { TopComponent[] tcs = mode.getTopComponents(); @@ -138,7 +140,7 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing } mode.dockInto(this); this.open(); - } + } } @Override @@ -151,7 +153,7 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing @Override protected void componentActivated() { //logger.log(Level.INFO, "ACTIVATED"); - super.componentActivated(); + super.componentActivated(); } @Override @@ -226,11 +228,40 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing */ @Override public void displayReport(String ingestReport) { - JOptionPane.showMessageDialog( - null, + + Object[] options = {"OK", + "Generate Report"}; + final int choice = JOptionPane.showOptionDialog(null, ingestReport, - "File Ingest Summary", - JOptionPane.INFORMATION_MESSAGE); + "Ingest Report", + JOptionPane.YES_NO_OPTION, + JOptionPane.INFORMATION_MESSAGE, + null, + options, + options[0]); + + final String reportActionName = "org.sleuthkit.autopsy.report.reportAction"; + Action reportAction = null; + + //find action by name from action lookup, without introducing cyclic dependency + if (choice == JOptionPane.NO_OPTION) { + List actions = Utilities.actionsForPath("Toolbars/File"); + for (Action a : actions) { + //separators are null actions + if (a != null) { + if (a.getClass().getCanonicalName().equals(reportActionName)) { + reportAction = a; + break; + } + } + } + + if (reportAction == null) + logger.log(Level.SEVERE, "Could not locate Action: " + reportActionName); + else reportAction.actionPerformed(null); + + } + } /** @@ -261,7 +292,6 @@ public final class IngestMessageTopComponent extends TopComponent implements Ing ingestDialog.setImage(image); ingestDialog.display(); */ - } @Override diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestServiceAbstract.java b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestServiceAbstract.java index fb67fec0ef..b8ffdf756f 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/IngestServiceAbstract.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/IngestServiceAbstract.java @@ -19,12 +19,15 @@ package org.sleuthkit.autopsy.ingest; +import java.beans.PropertyChangeListener; + /** * Base interface for ingest services */ public interface IngestServiceAbstract { public enum ServiceType {Image, FsContent}; + public static final String BCKGRND_JOBS_COMPLETED_EVT = "BCKGRND_JOBS_COMPLETED_EVT"; /** * notification from manager that brand new processing should be initiated. @@ -61,11 +64,28 @@ public interface IngestServiceAbstract { /** * A service can manage and use additional threads to perform some work in the background. * This method provides insight to the manager if the service has truly completed its work or not. + * + * * @return true if any background threads/workers managed by this service are still running - * false if all work has been done, or if background threads are not used by this service + * false if all work has been done, or if background threads are not managed by this service */ public boolean hasBackgroundJobsRunning(); + /** + * Register listener to notify when all background jobs managed by this service have completed and the service + * has truly finished. The service should first check if it has threads running, and then register the listener, all in a single atomic, synchronized operation, and return the result of the registration. + * Do not register the listener if the background threads are not running and will not run during this service invocation. + * If the service does use background threads it is required to implement this method properly and ensure the event is fired when the service-managed threads complete (are finished or cancelled) + * The event fired off should be IngestServiceAbstract.BCKGRND_JOBS_COMPLETED_EVT, with the instance of IngestServiceAbstract in the newValue parameter. + * The listeners should be reset at service init() - listeners are expected to register again as needed during the new service run. + * Typical use case is for ingest manager to try to register the listener for every service when the queue has been consumed, + * for a precise indication when all work is truly done. + * + * @param l listener + * @return true if listener registered, false otherwise (i.e. no background jobs were running, or the service does not manage additional threads) + */ + public boolean backgroundJobsCompleteListener(PropertyChangeListener l); + /** * @return does this service have a simple configuration? diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleFsContentIngestService.java b/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleFsContentIngestService.java index 41bc0b9f67..8819b72357 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleFsContentIngestService.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleFsContentIngestService.java @@ -18,9 +18,9 @@ */ package org.sleuthkit.autopsy.ingest.example; +import java.beans.PropertyChangeListener; import java.util.logging.Level; import java.util.logging.Logger; -import javax.swing.JPanel; import org.sleuthkit.autopsy.ingest.IngestManagerProxy; import org.sleuthkit.autopsy.ingest.IngestMessage; import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType; @@ -117,6 +117,11 @@ public class ExampleFsContentIngestService implements IngestServiceFsContent { return false; } + @Override + public boolean backgroundJobsCompleteListener(PropertyChangeListener l) { + return false; + } + @Override public void saveAdvancedConfiguration() { } diff --git a/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleImageIngestService.java b/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleImageIngestService.java index ae38dbf2ee..73ab812034 100644 --- a/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleImageIngestService.java +++ b/Ingest/src/org/sleuthkit/autopsy/ingest/example/ExampleImageIngestService.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.ingest.example; +import java.beans.PropertyChangeListener; import java.util.logging.Level; import java.util.logging.Logger; import org.sleuthkit.autopsy.ingest.IngestImageWorkerController; @@ -147,6 +148,11 @@ public final class ExampleImageIngestService implements IngestServiceImage { return false; } + @Override + public boolean backgroundJobsCompleteListener(PropertyChangeListener l) { + return false; + } + @Override public void saveAdvancedConfiguration() { } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Ingester.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Ingester.java index 8a7c5ef042..48c5f07340 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Ingester.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Ingester.java @@ -48,6 +48,7 @@ class Ingester { } @Override + @SuppressWarnings("FinalizeDeclaration") protected void finalize() throws Throwable { super.finalize(); diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java index d0f7e2096b..c9228d544a 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java @@ -844,7 +844,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec } - class TableEntry implements Comparable { + class TableEntry implements Comparable { Keyword keyword; @@ -853,12 +853,12 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec } @Override - public int compareTo(Object o) { - int keywords = this.keyword.getQuery().compareTo(((TableEntry) o).keyword.getQuery()); + public int compareTo(TableEntry te) { + int keywords = this.keyword.getQuery().compareTo(te.keyword.getQuery()); if (keywords != 0) { return keywords; } else { - return Boolean.valueOf(keyword.isLiteral()).compareTo(((TableEntry) o).keyword.isLiteral()); + return Boolean.valueOf(keyword.isLiteral()).compareTo(te.keyword.isLiteral()); } } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java index e9eada1663..3d64f4a671 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestService.java @@ -18,6 +18,8 @@ */ package org.sleuthkit.autopsy.keywordsearch; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -25,7 +27,6 @@ import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -import javax.swing.JPanel; import javax.swing.SwingUtilities; import javax.swing.SwingWorker; import org.apache.commons.lang.StringEscapeUtils; @@ -38,6 +39,7 @@ import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManagerProxy; import org.sleuthkit.autopsy.ingest.IngestMessage; import org.sleuthkit.autopsy.ingest.IngestMessage.MessageType; +import org.sleuthkit.autopsy.ingest.IngestServiceAbstract; import org.sleuthkit.autopsy.ingest.IngestServiceFsContent; import org.sleuthkit.autopsy.ingest.ServiceDataEvent; import org.sleuthkit.autopsy.keywordsearch.Ingester.IngesterException; @@ -66,13 +68,17 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent //private final Object lock = new Object(); private Thread timer; private Indexer indexer; - private SwingWorker searcher; + private Searcher searcher; private volatile boolean searcherDone = true; + private static PropertyChangeSupport pcs = null; private Map> currentResults; private volatile int messageID = 0; + private boolean processedFiles; private volatile boolean finalRun = false; + private volatile boolean finalRunComplete = false; private final String hashDBServiceName = "Hash Lookup"; private SleuthkitCase caseHandle = null; + // TODO: use a more robust method than checking file extension to determine // whether to try a file // supported extensions list from http://www.lucidimagination.com/devzone/technical-articles/content-extraction-tika @@ -108,6 +114,9 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent //notify depending service that keyword search (would) encountered error for this file return ProcessResult.ERROR; } + + if (processedFiles == false) + processedFiles = true; //check if time to commit and previous search is not running //commiting while searching causes performance issues @@ -151,11 +160,12 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent updateKeywords(); //run one last search as there are probably some new files committed - if (keywords != null && !keywords.isEmpty()) { + if (keywords != null && !keywords.isEmpty() && processedFiles == true) { finalRun = true; searcher = new Searcher(keywords); searcher.execute(); } else { + finalRunComplete = true; managerProxy.postMessage(IngestMessage.createMessage(++messageID, MessageType.INFO, this, "Completed")); } //postSummary(); @@ -191,6 +201,9 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent caseHandle = Case.getCurrentCase().getSleuthkitCase(); this.managerProxy = managerProxy; + + //this deregisters previously registered listeners at every init() + pcs = new PropertyChangeSupport(KeywordSearchIngestService.class); final Server.Core solrCore = KeywordSearch.getServer().getCore(); ingester = solrCore.getIngester(); @@ -209,7 +222,9 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent managerProxy.postMessage(IngestMessage.createWarningMessage(++messageID, instance, "No keywords in keyword list.", "Only indexing will be done and and keyword search will be skipped (it can be executed later again as ingest or using toolbar search feature).")); } + processedFiles = false; finalRun = false; + finalRunComplete = false; searcherDone = true; //make sure to start the initial searcher //keeps track of all results per run not to repeat reporting the same hits currentResults = new HashMap>(); @@ -271,6 +286,17 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent //no need to check timer thread } + + @Override + public synchronized boolean backgroundJobsCompleteListener(PropertyChangeListener l) { + if (finalRunComplete == true) + return false; + else { + pcs.addPropertyChangeListener(l); + return true; + } + + } private void commit() { ingester.commit(); @@ -468,16 +494,17 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent if (fsContent.getSize() < MAX_STRING_EXTRACT_SIZE) { if (!extractAndIngest(fsContent)) { logger.log(Level.INFO, "Failed to extract strings and ingest, file '" + fsContent.getName() + "' (id: " + fsContent.getId() + ")."); + ingestStatus.put(fsContent.getId(), IngestStatus.SKIPPED); } else { ingestStatus.put(fsContent.getId(), IngestStatus.EXTRACTED_INGESTED); } } else { - ingestStatus.put(fsContent.getId(), IngestStatus.SKIPPED); + //ingestStatus.put(fsContent.getId(), IngestStatus.SKIPPED); } } } - private class Searcher extends SwingWorker { + private class Searcher extends SwingWorker { private List keywords; private ProgressHandle progress; @@ -499,6 +526,7 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent @Override public boolean cancel() { + finalRunComplete = true; return Searcher.this.cancel(true); } }); @@ -655,9 +683,11 @@ public final class KeywordSearchIngestService implements IngestServiceFsContent //logger.log(Level.INFO, "Finished search"); if (finalRun) { + finalRunComplete = true; keywords.clear(); keywordLists.clear(); managerProxy.postMessage(IngestMessage.createMessage(++messageID, MessageType.INFO, KeywordSearchIngestService.instance, "Completed")); + pcs.firePropertyChange(IngestServiceAbstract.BCKGRND_JOBS_COMPLETED_EVT, null, KeywordSearchIngestService.this); } } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java index 71f90cc2c2..03e5ba8eef 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java @@ -396,7 +396,7 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel { } //single model entry - class TableEntry implements Comparable { + class TableEntry implements Comparable { String name; @@ -405,8 +405,8 @@ class KeywordSearchListsManagementPanel extends javax.swing.JPanel { } @Override - public int compareTo(Object o) { - return this.name.compareTo(((TableEntry) o).name); + public int compareTo(TableEntry te) { + return this.name.compareTo(te.name); } } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java index 74c3fe83c0..db3f8db9ea 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java @@ -506,7 +506,7 @@ class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer { } //single model entry - private class ListTableEntry implements Comparable { + private class ListTableEntry implements Comparable { String name; Boolean selected; @@ -520,8 +520,8 @@ class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer { } @Override - public int compareTo(Object o) { - return this.name.compareTo(((ListTableEntry) o).name); + public int compareTo(ListTableEntry e) { + return this.name.compareTo(e.name); } } } @@ -606,7 +606,7 @@ class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer { } //single model entry - private class KeywordTableEntry implements Comparable { + private class KeywordTableEntry implements Comparable { String name; Boolean regex; @@ -617,8 +617,8 @@ class KeywordSearchListsViewerPanel extends AbstractKeywordSearchPerformer { } @Override - public int compareTo(Object o) { - return this.name.compareTo(((KeywordTableEntry) o).name); + public int compareTo(KeywordTableEntry e) { + return this.name.compareTo(e.name); } } } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchUtil.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchUtil.java index a9f8a4744e..fc7abb5cce 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchUtil.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchUtil.java @@ -131,7 +131,9 @@ public class KeywordSearchUtil { //TODO escaping should be handled by blackboard public static String escapeForBlackBoard(String text) { try { - text = text.replaceAll("\\\\'", URLEncoder.encode("\\'", "UTF-8")); + //text = text.replaceAll("\\\\'", URLEncoder.encode("\\'", "UTF-8")); + text = text.replaceAll("'", URLEncoder.encode("'", "UTF-8")); + //text = text.replaceAll("\"", URLEncoder.encode("\"", "UTF-8")); //text = text.replaceAll("\\\\", URLEncoder.encode("\\", "UTF-8")); } catch (UnsupportedEncodingException ex) { } diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermComponentQuery.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermComponentQuery.java index 819e7984ee..f296739a34 100644 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermComponentQuery.java +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/TermComponentQuery.java @@ -199,7 +199,8 @@ public class TermComponentQuery implements KeywordSearchQuery { attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD_REGEXP.getTypeID(), MODULE_NAME, "", KeywordSearchUtil.escapeForBlackBoard(termsQuery))); //regex match - attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID(), MODULE_NAME, "", regexMatch)); + final String regexMatchEscaped = KeywordSearchUtil.escapeForBlackBoard(regexMatch); + attributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_KEYWORD.getTypeID(), MODULE_NAME, "", regexMatchEscaped)); //list if (listName == null) { listName = ""; @@ -214,7 +215,7 @@ public class TermComponentQuery implements KeywordSearchQuery { if (keywordQuery != null) { BlackboardAttribute.ATTRIBUTE_TYPE selType = keywordQuery.getType(); if (selType != null) { - BlackboardAttribute selAttr = new BlackboardAttribute(selType.getTypeID(), MODULE_NAME, "", regexMatch); + BlackboardAttribute selAttr = new BlackboardAttribute(selType.getTypeID(), MODULE_NAME, "", regexMatchEscaped); attributes.add(selAttr); } } @@ -297,7 +298,7 @@ public class TermComponentQuery implements KeywordSearchQuery { logger.log(Level.INFO, "Executing TermsComponent query: " + q.toString()); - final SwingWorker worker = new TermsQueryWorker(q); + final SwingWorker, Void> worker = new TermsQueryWorker(q); worker.execute(); } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java index fad833d7a3..8bdee2792b 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Chrome.java @@ -31,6 +31,8 @@ public class Chrome { + "datetime(urls.last_visit_time/1000000-11644473600,'unixepoch','localtime') as last_visit_time, urls.hidden, visits.visit_time, visits.from_visit, visits.transition FROM urls, visits WHERE urls.id = visits.url"; public static final String chcookiequery = "select name, value, host, expires_utc, datetime(last_access_utc/1000000-11644473600,'unixepoch','localtime') as last_access_utc, creation_utc from cookies"; public static final String chbookmarkquery = "SELECT starred.title, urls.url, starred.date_added, starred.date_modified, urls.typed_count, datetime(urls.last_visit_time/1000000-11644473600,'unixepoch','localtime') as urls._last_visit_time FROM starred INNER JOIN urls ON urls.id = starred.url_id"; + public static final String chdownloadquery = "select full_path, url, start_time, received_bytes from `downloads`"; + public static final String chloginquery = "select origin_url, username_value, signon_realm from `logins`"; private final Logger logger = Logger.getLogger(this.getClass().getName()); public int ChromeCount = 0; @@ -82,7 +84,7 @@ public class Chrome { bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(),"RecentActivity","",temprs.getString("url"))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(),"RecentActivity","Last Accessed",temprs.getString("last_visit_time"))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID(),"RecentActivity","",temprs.getString("from_visit"))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(),"RecentActivity","",((temprs.getString("title") != null) ? temprs.getString("title") : "No Title"))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(),"RecentActivity","",((temprs.getString("title") != null) ? temprs.getString("title") : ""))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","Chrome")); bbart.addAttributes(bbattributes); @@ -144,7 +146,7 @@ public class Chrome { bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity", "", temprs.getString("host"))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),"RecentActivity", "Last Visited",temprs.getString("access_utc"))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(),"RecentActivity", "",temprs.getString("value"))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","Title",((temprs.getString("name") != null) ? temprs.getString("name") : "No name"))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","Title",((temprs.getString("name") != null) ? temprs.getString("name") : ""))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","Chrome")); bbart.addAttributes(bbattributes); } @@ -202,8 +204,132 @@ public class Chrome { BlackboardArtifact bbart = FFSqlitedb.get(j).newArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK); Collection bbattributes = new ArrayList(); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(),"RecentActivity","Last Visited",temprs.getString("last_visit_time"))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity","",((temprs.getString("url") != null) ? temprs.getString("url") : "No URL"))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","", ((temprs.getString("title") != null) ? temprs.getString("title").replaceAll("'", "''") : "No Title"))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity","",((temprs.getString("url") != null) ? temprs.getString("url") : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","", ((temprs.getString("title") != null) ? temprs.getString("title").replaceAll("'", "''") : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","Chrome")); + bbart.addAttributes(bbattributes); + + } + tempdbconnect.closeConnection(); + temprs.close(); + + } + catch (Exception ex) + { + logger.log(Level.WARNING, "Error while trying to read into a sqlite db." + connectionString, ex); + } + j++; + dbFile.delete(); + } + } + catch (SQLException ex) + { + logger.log(Level.WARNING, "Error while trying to get Chrome SQLite db.", ex); + } + catch(IOException ioex) + { + logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex); + } + + //Downloads section + // This gets the downloads info + try + { + Case currentCase = Case.getCurrentCase(); // get the most updated case + SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + List FFSqlitedb; + ResultSet rs = tempDb.runQuery("select * from tsk_files where name LIKE 'History' and parent_path LIKE '%Chrome%' and fs_obj_id = '" + image + "'"); + FFSqlitedb = tempDb.resultSetToFsContents(rs); + rs.close(); + rs.getStatement().close(); + + int j = 0; + + while (j < FFSqlitedb.size()) + { + String temps = currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db"; + String connectionString = "jdbc:sqlite:" + temps; + ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db")); + File dbFile = new File(temps); + if (controller.isCancelled() ) { + dbFile.delete(); + break; + } + try + { + dbconnect tempdbconnect = new dbconnect("org.sqlite.JDBC",connectionString); + ResultSet temprs = tempdbconnect.executeQry(chdownloadquery); + while(temprs.next()) + { + BlackboardArtifact bbart = FFSqlitedb.get(j).newArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD); + Collection bbattributes = new ArrayList(); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(),"RecentActivity","Last Visited",temprs.getString("start_time"))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity","",((temprs.getString("url") != null) ? temprs.getString("url") : ""))); + //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","", ((temprs.getString("title") != null) ? temprs.getString("title").replaceAll("'", "''") : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), "Recent Activity", "", temprs.getString("full_path"))); + + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","Chrome")); + bbart.addAttributes(bbattributes); + + } + tempdbconnect.closeConnection(); + temprs.close(); + + } + catch (Exception ex) + { + logger.log(Level.WARNING, "Error while trying to read into a sqlite db." + connectionString, ex); + } + j++; + dbFile.delete(); + } + } + catch (SQLException ex) + { + logger.log(Level.WARNING, "Error while trying to get Chrome SQLite db.", ex); + } + catch(IOException ioex) + { + logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex); + } + + //Login/Password section + // This gets the user info + try + { + Case currentCase = Case.getCurrentCase(); // get the most updated case + SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + List FFSqlitedb; + ResultSet rs = tempDb.runQuery("select * from tsk_files where name LIKE 'signons.sqlite' and parent_path LIKE '%Chrome%' and fs_obj_id = '" + image + "'"); + FFSqlitedb = tempDb.resultSetToFsContents(rs); + rs.close(); + rs.getStatement().close(); + + int j = 0; + + while (j < FFSqlitedb.size()) + { + String temps = currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db"; + String connectionString = "jdbc:sqlite:" + temps; + ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db")); + File dbFile = new File(temps); + if (controller.isCancelled() ) { + dbFile.delete(); + break; + } + try + { + dbconnect tempdbconnect = new dbconnect("org.sqlite.JDBC",connectionString); + ResultSet temprs = tempdbconnect.executeQry(chloginquery); + while(temprs.next()) + { + BlackboardArtifact bbart = FFSqlitedb.get(j).newArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY); + Collection bbattributes = new ArrayList(); + //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(),"RecentActivity","Last Visited",temprs.getString("start_time"))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity","",((temprs.getString("origin_url") != null) ? temprs.getString("origin_url") : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_USERNAME.getTypeID(), "RecentActivity","", ((temprs.getString("username_value") != null) ? temprs.getString("username_value").replaceAll("'", "''") : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DOMAIN.getTypeID(), "Recent Activity", "", temprs.getString("signon_realm"))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","Chrome")); bbart.addAttributes(bbattributes); diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractAll.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractAll.java index 84c0333456..6cc7779ff5 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractAll.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractAll.java @@ -14,7 +14,7 @@ import org.sleuthkit.autopsy.ingest.IngestImageWorkerController; public class ExtractAll { void ExtractAll(){ - + } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java index 1d3440d940..1e0968b8d6 100755 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractIE.java @@ -292,9 +292,7 @@ public class ExtractIE { // implements BrowserActivity { PASCO_RESULTS_LIST.add(PASCO_RESULTS_LUT); } catch (TskException ex) { Exceptions.printStackTrace(ex); - } catch (SQLException ex) { - logger.log(Level.WARNING, "Couldn't find file with id: " + artObjId, ex); - } + } } } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java index e9fa80a8a9..366382e6b8 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ExtractRegistry.java @@ -42,7 +42,7 @@ public class ExtractRegistry { public Logger logger = Logger.getLogger(this.getClass().getName()); private String RR_PATH; boolean rrFound = false; - + private int sysid; ExtractRegistry(){ final File rrRoot = InstalledFileLocator.getDefault().locate("rr", ExtractRegistry.class.getPackage().getName(), false); if (rrRoot == null) { @@ -53,7 +53,18 @@ public class ExtractRegistry { else { rrFound = true; } - + try{ + Case currentCase = Case.getCurrentCase(); // get the most updated case + SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + ResultSet artset = tempDb.runQuery("SELECT * from blackboard_artifact_types WHERE type_name = 'TSK_SYS_INFO'"); + + while (artset.next()){ + sysid = artset.getInt("artifact_type_id"); + } + } + catch(Exception e){ + + } final String rrHome = rrRoot.getAbsolutePath(); logger.log(Level.INFO, "RegRipper home: " + rrHome); @@ -175,7 +186,9 @@ public void getregistryfiles(List image, IngestImageWorkerController con { Case currentCase = Case.getCurrentCase(); // get the most updated case SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + try { + String regString = new Scanner(new File(regRecord)).useDelimiter("\\Z").next(); String startdoc = ""; String result = regString.replaceAll("----------------------------------------",""); @@ -199,7 +212,7 @@ public void getregistryfiles(List image, IngestImageWorkerController con Element artroot = tempnode.getChild("artifacts"); List artlist = artroot.getChildren(); - BlackboardArtifact bbart = tempDb.getContentById(orgId).newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT); + Collection bbattributes = new ArrayList(); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(), "RecentActivity", context, time)); Iterator aiterator = artlist.iterator(); @@ -210,16 +223,27 @@ public void getregistryfiles(List image, IngestImageWorkerController con bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity", context, name)); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(), "RecentActivity", context, value)); } - - - - + if("recentdocs".equals(context)){ + BlackboardArtifact bbart = tempDb.getContentById(orgId).newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT); bbart.addAttributes(bbattributes); + } + else if("runMRU".equals(context)){ + BlackboardArtifact bbart = tempDb.getContentById(orgId).newArtifact(ARTIFACT_TYPE.TSK_RECENT_OBJECT); + bbart.addAttributes(bbattributes); + + } + else + { + + BlackboardArtifact bbart = tempDb.getContentById(orgId).newArtifact(sysid); + bbart.addAttributes(bbattributes); + } + } } catch (Exception ex) { - String hi = ""; + logger.log(Level.WARNING, "Error while trying to read into a sqlite db." + ex); } diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java index 2380a191eb..47c27467ff 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Firefox.java @@ -31,6 +31,7 @@ public class Firefox { private static final String ffquery = "SELECT moz_historyvisits.id,url,title,visit_count,datetime(moz_historyvisits.visit_date/1000000,'unixepoch','localtime') as visit_date,from_visit,(SELECT url FROM moz_places WHERE id=moz_historyvisits.from_visit) as ref FROM moz_places, moz_historyvisits WHERE moz_places.id = moz_historyvisits.place_id AND hidden = 0"; private static final String ffcookiequery = "SELECT name,value,host,expiry,datetime(moz_cookies.lastAccessed/1000000,'unixepoch','localtime') as lastAccessed,creationTime FROM moz_cookies"; private static final String ffbookmarkquery = "SELECT fk, moz_bookmarks.title, url FROM moz_bookmarks INNER JOIN moz_places ON moz_bookmarks.fk=moz_places.id"; + private static final String ffdownloadquery = "select target, source, startTime, maxBytes from `moz_downloads`"; public Logger logger = Logger.getLogger(this.getClass().getName()); @@ -88,8 +89,8 @@ public class Firefox { Collection bbattributes = new ArrayList(); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(),"RecentActivity","",temprs.getString("url"))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(),"RecentActivity","Last Visited",temprs.getString("visit_date"))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID(),"RecentActivity","",((temprs.getString("ref") != null) ? temprs.getString("ref") : "None"))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(),"RecentActivity","",((temprs.getString("title") != null) ? temprs.getString("title") : "No Title"))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_REFERRER.getTypeID(),"RecentActivity","",((temprs.getString("ref") != null) ? temprs.getString("ref") : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(),"RecentActivity","",((temprs.getString("title") != null) ? temprs.getString("title") : ""))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","FireFox")); bbart.addAttributes(bbattributes); @@ -100,8 +101,8 @@ public class Firefox { { BlackboardArtifact bbart = FFSqlitedb.get(j).newArtifact(ARTIFACT_TYPE.TSK_WEB_BOOKMARK); Collection bbattributes = new ArrayList(); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(),"RecentActivity","",((temprs.getString("url") != null) ? temprs.getString("url") : "No URL"))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","", ((temprs.getString("title") != null) ? temprs.getString("title").replaceAll("'", "''") : "No Title"))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(),"RecentActivity","",((temprs.getString("url") != null) ? temprs.getString("url") : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","", ((temprs.getString("title") != null) ? temprs.getString("title").replaceAll("'", "''") : ""))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","FireFox")); bbart.addAttributes(bbattributes); } @@ -168,7 +169,7 @@ public class Firefox { bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity", "", temprs.getString("host"))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(), "RecentActivity", "Last Visited", temprs.getString("lastAccessed"))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_VALUE.getTypeID(), "RecentActivity", "", temprs.getString("value"))); - bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","Title",((temprs.getString("name") != null) ? temprs.getString("name") : "No name"))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","Title",((temprs.getString("name") != null) ? temprs.getString("name") : ""))); bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","FireFox")); bbart.addAttributes(bbattributes); @@ -193,6 +194,69 @@ public class Firefox { { logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex); } + + + //Downloads section + // This gets the downloads info + try + { + Case currentCase = Case.getCurrentCase(); // get the most updated case + SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + List FFSqlitedb; + ResultSet rs = tempDb.runQuery("select * from tsk_files where name LIKE 'downloads.sqlite' and parent_path LIKE '%Firefox%' and fs_obj_id = '" + image + "'"); + FFSqlitedb = tempDb.resultSetToFsContents(rs); + rs.close(); + rs.getStatement().close(); + + int j = 0; + + while (j < FFSqlitedb.size()) + { + String temps = currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db"; + String connectionString = "jdbc:sqlite:" + temps; + ContentUtils.writeToFile(FFSqlitedb.get(j), new File(currentCase.getTempDirectory() + "\\" + FFSqlitedb.get(j).getName().toString() + j + ".db")); + File dbFile = new File(temps); + if (controller.isCancelled() ) { + dbFile.delete(); + break; + } + try + { + dbconnect tempdbconnect = new dbconnect("org.sqlite.JDBC",connectionString); + ResultSet temprs = tempdbconnect.executeQry(ffdownloadquery); + while(temprs.next()) + { + BlackboardArtifact bbart = FFSqlitedb.get(j).newArtifact(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD); + Collection bbattributes = new ArrayList(); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_LAST_ACCESSED.getTypeID(),"RecentActivity","Last Visited",temprs.getString("startTime"))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL.getTypeID(), "RecentActivity","",((temprs.getString("source") != null) ? temprs.getString("source") : ""))); + //bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_NAME.getTypeID(), "RecentActivity","", ((temprs.getString("title") != null) ? temprs.getString("title").replaceAll("'", "''") : ""))); + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PATH.getTypeID(), "Recent Activity", "", temprs.getString("target"))); + + bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_PROG_NAME.getTypeID(),"RecentActivity","","Chrome")); + bbart.addAttributes(bbattributes); + + } + tempdbconnect.closeConnection(); + temprs.close(); + + } + catch (Exception ex) + { + logger.log(Level.WARNING, "Error while trying to read into a sqlite db." + connectionString, ex); + } + j++; + dbFile.delete(); + } + } + catch (SQLException ex) + { + logger.log(Level.WARNING, "Error while trying to get FireFox SQLite db.", ex); + } + catch(IOException ioex) + { + logger.log(Level.WARNING, "Error while trying to write to the file system.", ioex); + } } } //@Override diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestService.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestService.java index 9e9332bf8e..02526d349e 100644 --- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestService.java +++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/RAImageIngestService.java @@ -18,12 +18,13 @@ */ package org.sleuthkit.autopsy.recentactivity; +import java.beans.PropertyChangeListener; +import java.sql.ResultSet; import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import javax.swing.JPanel; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.ingest.IngestImageWorkerController; import org.sleuthkit.autopsy.ingest.IngestManager; @@ -80,7 +81,28 @@ public final class RAImageIngestService implements IngestServiceImage { try { //do the work for(FileSystem img : imageFS ) + try{ + ResultSet artset = sCurrentCase.runQuery("SELECT * from blackboard_artifact_types WHERE type_name = 'TSK_SYS_INFO'"); + int artcount = 0; + while (artset.next()){ + artcount++; + } + + // artset.beforeFirst(); + if(artcount > 0) + { + } + else + { + int artint = sCurrentCase.addArtifactType("TSK_SYS_INFO", "System Information"); + } + + } + catch(Exception e) + { + + } ext.extractToBlackboard(controller, fsIds); @@ -162,4 +184,10 @@ public final class RAImageIngestService implements IngestServiceImage { public boolean hasBackgroundJobsRunning() { return false; } + + + @Override + public boolean backgroundJobsCompleteListener(PropertyChangeListener l) { + return false; + } } diff --git a/Report/src/org/sleuthkit/autopsy/report/report.java b/Report/src/org/sleuthkit/autopsy/report/report.java index 5dadd47220..ae8c5a2a57 100644 --- a/Report/src/org/sleuthkit/autopsy/report/report.java +++ b/Report/src/org/sleuthkit/autopsy/report/report.java @@ -5,16 +5,14 @@ package org.sleuthkit.autopsy.report; import java.sql.ResultSet; -import java.sql.SQLException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; -import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; -import org.sleuthkit.datamodel.FsContent; import org.sleuthkit.datamodel.SleuthkitCase; /** @@ -199,4 +197,57 @@ public HashMap> getHashHit() { return reportMap; } +@Override +public String getGroupedKeywordHit() { + StringBuilder table = new StringBuilder(); + HashMap> reportMap = new HashMap(); + Case currentCase = Case.getCurrentCase(); // get the most updated case + SleuthkitCase tempDb = currentCase.getSleuthkitCase(); + try + { + ResultSet uniqueresults = tempDb.runQuery("SELECT DISTINCT value_text from blackboard_attributes where attribute_type_id = '10' order by value_text ASC"); + while(uniqueresults.next()) + { + table.append("").append(uniqueresults.getString("value_text")).append(""); + table.append(""); + ArrayList artlist = new ArrayList(); + ResultSet tempresults = tempDb.runQuery("select DISTINCT artifact_id from blackboard_attributes where attribute_type_id = '10' and value_text = '" + uniqueresults.getString("value_text") +"'"); + while(tempresults.next()) + { + artlist.add(tempDb.getBlackboardArtifact(tempresults.getLong("artifact_id"))); + } + for(BlackboardArtifact art : artlist) + { + String filename = tempDb.getFsContentById(art.getObjectID()).getName(); + String preview = ""; + String set = ""; + table.append(""); + ArrayList tempatts = art.getAttributes(); + for(BlackboardAttribute att : tempatts) + { + if(att.getAttributeTypeID() == 12) + { + preview = ""; + } + if(att.getAttributeTypeID() == 13) + { + set = ""; + } + } + table.append(preview).append(set).append(""); + } + + + table.append("
").append("File Name").append("PreviewKeyword List
").append(filename).append("" + att.getValueString() + "" + att.getValueString() + "


"); + } + } + catch (Exception e) + { + Logger.getLogger(report.class.getName()).log(Level.INFO, "Exception occurred", e); + } + + String result = table.toString(); + return result; +} + } \ No newline at end of file diff --git a/Report/src/org/sleuthkit/autopsy/report/reportFilter.form b/Report/src/org/sleuthkit/autopsy/report/reportFilter.form index dac82f751f..8c3a8123f9 100644 --- a/Report/src/org/sleuthkit/autopsy/report/reportFilter.form +++ b/Report/src/org/sleuthkit/autopsy/report/reportFilter.form @@ -32,34 +32,35 @@ + - - - - - - + + - + + + + + - + @@ -79,13 +80,12 @@ - - - - - + + + + + - diff --git a/Report/src/org/sleuthkit/autopsy/report/reportFilter.java b/Report/src/org/sleuthkit/autopsy/report/reportFilter.java index 2ecee61ef0..f3404291f0 100644 --- a/Report/src/org/sleuthkit/autopsy/report/reportFilter.java +++ b/Report/src/org/sleuthkit/autopsy/report/reportFilter.java @@ -106,26 +106,28 @@ public class reportFilter extends javax.swing.JPanel { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() + .addGap(38, 38, 38) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGap(28, 28, 28) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jCheckBox3) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jCheckBox2) - .addComponent(jCheckBox1) - .addComponent(cancelButton)) + .addComponent(jCheckBox1)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jCheckBox5) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jCheckBox4) - .addComponent(progBar, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 188, javax.swing.GroupLayout.PREFERRED_SIZE)))))) + .addComponent(jCheckBox4)))) + .addGap(69, 69, 69)) .addGroup(layout.createSequentialGroup() - .addGap(106, 106, 106) - .addComponent(jButton1))) - .addContainerGap(108, Short.MAX_VALUE)) + .addComponent(jButton1) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 15, Short.MAX_VALUE) + .addComponent(cancelButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(progBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(42, 42, 42))) + .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -141,12 +143,11 @@ public class reportFilter extends javax.swing.JPanel { .addGap(18, 18, 18) .addComponent(jCheckBox3) .addGap(18, 18, 18) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(layout.createSequentialGroup() - .addComponent(jButton1) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(progBar, javax.swing.GroupLayout.DEFAULT_SIZE, 25, Short.MAX_VALUE)) - .addComponent(cancelButton)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(progBar, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jButton1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(cancelButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addContainerGap()) ); }// //GEN-END:initComponents diff --git a/Report/src/org/sleuthkit/autopsy/report/reportHTML.java b/Report/src/org/sleuthkit/autopsy/report/reportHTML.java index 4c764d06e0..350ac7300d 100644 --- a/Report/src/org/sleuthkit/autopsy/report/reportHTML.java +++ b/Report/src/org/sleuthkit/autopsy/report/reportHTML.java @@ -5,7 +5,6 @@ package org.sleuthkit.autopsy.report; import java.io.BufferedWriter; -import java.io.File; import java.io.FileWriter; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -13,13 +12,16 @@ import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.Map.Entry; +import java.util.TreeMap; import java.util.logging.Level; import java.util.logging.Logger; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.FsContent; import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskData; /** * @@ -31,16 +33,65 @@ public class reportHTML { public static StringBuilder formatted_Report = new StringBuilder(); public static String htmlPath = ""; public reportHTML (HashMap> report, reportFilter rr){ - + + //This is literally a terrible way to count up all the types of artifacts, and doesn't include any added ones. + //Unlike the XML report, which is dynamic, this is formatted and needs to be redone later instead of being hardcoded. + + int countGen = 0; + int countWebBookmark = 0; + int countWebCookie = 0; + int countWebHistory = 0; + int countWebDownload = 0; + int countRecentObjects = 0; + int countTrackPoint = 0; + int countInstalled = 0; + int countKeyword = 0; + int countHash = 0; + for (Entry> entry : report.entrySet()) { + if(entry.getKey().getArtifactTypeID() == 1){ + countGen++; + } + if(entry.getKey().getArtifactTypeID() == 2){ + countWebBookmark++; + } + if(entry.getKey().getArtifactTypeID() == 3){ + + countWebCookie++; + } + if(entry.getKey().getArtifactTypeID() == 4){ + + countWebHistory++; + } + if(entry.getKey().getArtifactTypeID() == 5){ + countWebDownload++; + } + if(entry.getKey().getArtifactTypeID() == 6){ + countRecentObjects++; + } + if(entry.getKey().getArtifactTypeID() == 7){ + countTrackPoint++; + } + if(entry.getKey().getArtifactTypeID() == 8){ + countInstalled++; + } + if(entry.getKey().getArtifactTypeID() == 9){ + countKeyword++; + } + if(entry.getKey().getArtifactTypeID() == 10){ + countHash++; + } + } try{ + + String ingestwarning = "

Warning, this report was run before ingest services completed!

"; Case currentCase = Case.getCurrentCase(); // get the most updated case SleuthkitCase skCase = currentCase.getSleuthkitCase(); String caseName = currentCase.getName(); - String rrpath = System.getProperty("user.dir"); - rrpath = rrpath.substring(0, rrpath.length()-14); - rrpath = rrpath + "autopsy\\thirdparty\\"; Integer imagecount = currentCase.getImageIDs().length; + Integer totalfiles = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG); + Integer totaldirs = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR); + int reportsize = report.size(); Integer filesystemcount = currentCase.getRootObjectsCount(); DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy"); @@ -68,20 +119,27 @@ public reportHTML (HashMap> re // Add summary information now formatted_Report.append("

Report for Case: ").append(caseName).append("

"); + if(IngestManager.getDefault().isIngestRunning()) + { + formatted_Report.append(ingestwarning); + } formatted_Report.append("

Case Summary

HTML Report Generated by Autopsy 3 on ").append(datetime).append("

    "); formatted_Report.append("
  • # of Images: ").append(imagecount).append("
  • "); formatted_Report.append("
  • FileSystems: ").append(filesystemcount).append("
  • "); - String tableHeader = ""; - StringBuilder nodeGen = new StringBuilder("

    General Information

    " + tableHeader); - StringBuilder nodeWebBookmark = new StringBuilder("

    Web Bookmarks

    " + tableHeader); - StringBuilder nodeWebCookie = new StringBuilder("

    Web Cookies

    " + tableHeader); - StringBuilder nodeWebHistory = new StringBuilder("

    Web History

    " + tableHeader); - StringBuilder nodeWebDownload = new StringBuilder("

    Web Downloads

    " + tableHeader); - StringBuilder nodeRecentObjects = new StringBuilder("

    Recent Documents

    " + tableHeader); - StringBuilder nodeTrackPoint = new StringBuilder("

    Track Points

    " + tableHeader); - StringBuilder nodeInstalled = new StringBuilder("

    Installed Programs

    " + tableHeader); - StringBuilder nodeKeyword = new StringBuilder("

    Keyword Search Hits

    " + tableHeader); - StringBuilder nodeHash = new StringBuilder("

    Hashset Hits

    " + tableHeader); + formatted_Report.append("
  • # of Files: ").append(totalfiles.toString()).append("
  • "); + formatted_Report.append("
  • # of Dirs: ").append(totaldirs.toString()).append("
  • "); + formatted_Report.append("
  • # of Artifacts: ").append(reportsize).append("
  • "); + String tableHeader = "
    Artifact IDNameSizeAttributeValue
    "; + StringBuilder nodeGen = new StringBuilder("

    General Information (").append(countGen).append(")

    ").append(tableHeader).append(""); + StringBuilder nodeWebBookmark = new StringBuilder("

    Web Bookmarks (").append(countWebBookmark).append(")

    ").append(tableHeader).append(""); + StringBuilder nodeWebCookie = new StringBuilder("

    Web Cookies (").append(countWebCookie).append(")

    ").append(tableHeader).append(""); + StringBuilder nodeWebHistory = new StringBuilder("

    Web History (").append(countWebHistory).append(")

    ").append(tableHeader).append(""); + StringBuilder nodeWebDownload = new StringBuilder("

    Web Downloads (").append(countWebDownload).append(")

    ").append(tableHeader).append(""); + StringBuilder nodeRecentObjects = new StringBuilder("

    Recent Documents (").append(countRecentObjects).append(")

    ").append(tableHeader).append(""); + StringBuilder nodeTrackPoint = new StringBuilder("

    Track Points (").append(countTrackPoint).append(")

    ").append(tableHeader).append(""); + StringBuilder nodeInstalled = new StringBuilder("

    Installed Programs (").append(countInstalled).append(")

    ").append(tableHeader).append(""); + StringBuilder nodeKeyword = new StringBuilder("

    Keyword Search Hits (").append(countKeyword).append(")

    "); + StringBuilder nodeHash = new StringBuilder("

    Hashset Hits (").append(countHash).append(")

    ").append(tableHeader).append(""); for (Entry> entry : report.entrySet()) { if(reportFilter.cancel == true){ @@ -95,64 +153,103 @@ public reportHTML (HashMap> re Long filesize = file.getSize(); - - - // Get all the attributes for this guy + + TreeMap attributes = new TreeMap(); + // Get all the attributes, line them up to be added. for (BlackboardAttribute tempatt : entry.getValue()) { - if(reportFilter.cancel == true){ + if(reportFilter.cancel == true){ break; } - artifact.append(""); - //artifact.append("Path: ").append(file.getParentPath()); - artifact.append(""); - StringBuilder attribute = new StringBuilder(""); - attribute.append(""); - //attribute.append("
  • Context: ").append(tempatt.getContext()).append("
  • "); - artifact.append(attribute); + int type = tempatt.getAttributeTypeID(); + String value = tempatt.getValueString(); + attributes.put(type, value); cc++; } - //artifact.append(""); + + if(entry.getKey().getArtifactTypeID() == 1){ + + artifact.append(""); nodeGen.append(artifact); } if(entry.getKey().getArtifactTypeID() == 2){ + artifact.append(""); + artifact.append(""); + artifact.append(""); + artifact.append(""); nodeWebBookmark.append(artifact); } if(entry.getKey().getArtifactTypeID() == 3){ - + artifact.append(""); + artifact.append(""); + artifact.append(""); + artifact.append(""); + artifact.append(""); + artifact.append(""); nodeWebCookie.append(artifact); } if(entry.getKey().getArtifactTypeID() == 4){ - + artifact.append(""); + artifact.append(""); + artifact.append(""); + artifact.append(""); + artifact.append(""); + artifact.append(""); nodeWebHistory.append(artifact); } if(entry.getKey().getArtifactTypeID() == 5){ + artifact.append(""); + artifact.append(""); + artifact.append(""); + artifact.append(""); + artifact.append(""); nodeWebDownload.append(artifact); } if(entry.getKey().getArtifactTypeID() == 6){ + artifact.append(""); + artifact.append(""); + artifact.append(""); nodeRecentObjects.append(artifact); } if(entry.getKey().getArtifactTypeID() == 7){ + artifact.append(""); + artifact.append(""); + artifact.append(""); nodeTrackPoint.append(artifact); } if(entry.getKey().getArtifactTypeID() == 8){ + artifact.append(""); + artifact.append(""); + artifact.append(""); nodeInstalled.append(artifact); } if(entry.getKey().getArtifactTypeID() == 9){ - nodeKeyword.append(artifact); + + // artifact.append("
    AttributeValue
    URLTitleProgram
    URLDateNameValueProgram
    URLDateReferrerTitleProgram
    FileSourceTimeProgram
    Artifact IDNameSizeNamePath
    Artifact IDNameSizeAttributeValue
    Artifact IDNameSizeAttributeValue
    Artifact IDNameSizeHashset Name
    ").append(objId.toString()); - artifact.append("").append(file.getName().toString()).append("").append(filesize.toString()).append("").append(tempatt.getAttributeTypeDisplayName()).append("").append(tempatt.getValueString()).append("
    ").append(attributes.get(1)).append("").append(attributes.get(3)).append("").append(attributes.get(4)).append("
    ").append(attributes.get(1)).append("").append(attributes.get(2)).append("").append(attributes.get(3)).append("").append(attributes.get(6)).append("").append(attributes.get(4)).append("
    ").append(attributes.get(1)).append("").append(attributes.get(2)).append("").append(attributes.get(32)).append("").append(attributes.get(3)).append("").append(attributes.get(4)).append("
    ").append(attributes.get(8)).append("").append(attributes.get(1)).append("").append(attributes.get(2)).append("").append(attributes.get(4)).append("
    ").append(objId.toString()); + artifact.append("").append(file.getName().toString()).append("").append(filesize.toString()).append("
    ").append(objId.toString()); + artifact.append("").append(file.getName().toString()).append("").append(filesize.toString()).append("
    ").append(objId.toString()); + artifact.append("").append(file.getName().toString()).append("").append(filesize.toString()).append("
    "); + + // artifact.append("
    Artifact IDNameSize
    "); + // nodeKeyword.append(artifact); } if(entry.getKey().getArtifactTypeID() == 10){ + artifact.append("").append(objId.toString()); + artifact.append("").append(file.getName().toString()).append(""); + artifact.append("").append(filesize.toString()).append(""); + //artifact.append("").append(attributes.get(31)).append(""); + artifact.append("").append(attributes.get(30)).append(""); + artifact.append(""); nodeHash.append(artifact); } cc++; rr.progBarSet(cc); } //Add them back in order - formatted_Report.append(nodeGen); - formatted_Report.append(""); + //formatted_Report.append(nodeGen); + // formatted_Report.append(""); formatted_Report.append(nodeWebBookmark); formatted_Report.append(""); formatted_Report.append(nodeWebCookie); @@ -163,19 +260,25 @@ public reportHTML (HashMap> re formatted_Report.append(""); formatted_Report.append(nodeRecentObjects); formatted_Report.append(""); - formatted_Report.append(nodeTrackPoint); - formatted_Report.append(""); + // formatted_Report.append(nodeTrackPoint); + //formatted_Report.append(""); formatted_Report.append(nodeInstalled); - formatted_Report.append(""); + formatted_Report.append(""); formatted_Report.append(nodeKeyword); - formatted_Report.append(""); + if(countKeyword > 0){ + report keywords = new report(); + formatted_Report.append(keywords.getGroupedKeywordHit()); + // " + // formatted_Report.append("
    Artifact IDNameSize
    "); + } + formatted_Report.append(nodeHash); formatted_Report.append(""); //end of master loop formatted_Report.append(""); - htmlPath = currentCase.getCaseDirectory()+"/Temp/" + caseName + "-" + datenotime + ".html"; + htmlPath = currentCase.getCaseDirectory()+"/Reports/" + caseName + "-" + datenotime + ".html"; BufferedWriter out = new BufferedWriter(new FileWriter(htmlPath)); out.write(formatted_Report.toString()); diff --git a/Report/src/org/sleuthkit/autopsy/report/reportInterface.java b/Report/src/org/sleuthkit/autopsy/report/reportInterface.java index d94b62e943..ba8f3ef6f1 100644 --- a/Report/src/org/sleuthkit/autopsy/report/reportInterface.java +++ b/Report/src/org/sleuthkit/autopsy/report/reportInterface.java @@ -22,4 +22,5 @@ public interface reportInterface{ public HashMap> getRecentObject(); public HashMap> getHashHit(); public HashMap> getKeywordHit(); + public String getGroupedKeywordHit(); } diff --git a/Report/src/org/sleuthkit/autopsy/report/reportPanel.form b/Report/src/org/sleuthkit/autopsy/report/reportPanel.form index 2f20df384e..39a8765e76 100644 --- a/Report/src/org/sleuthkit/autopsy/report/reportPanel.form +++ b/Report/src/org/sleuthkit/autopsy/report/reportPanel.form @@ -7,6 +7,9 @@ + + + diff --git a/Report/src/org/sleuthkit/autopsy/report/reportPanel.java b/Report/src/org/sleuthkit/autopsy/report/reportPanel.java index c32603aa97..c03e38ccfe 100644 --- a/Report/src/org/sleuthkit/autopsy/report/reportPanel.java +++ b/Report/src/org/sleuthkit/autopsy/report/reportPanel.java @@ -10,9 +10,11 @@ */ package org.sleuthkit.autopsy.report; import java.awt.event.ActionListener; +import java.io.BufferedWriter; import java.io.FileOutputStream; +import java.io.FileWriter; import java.io.IOException; -import javax.swing.filechooser.FileFilter; +import org.jdom.output.XMLOutputter; /** * @@ -42,6 +44,8 @@ public class reportPanel extends javax.swing.JPanel { jButton1 = new javax.swing.JButton(); saveReport = new javax.swing.JButton(); + setFocusTraversalPolicyProvider(true); + jEditorPane1.setContentType(org.openide.util.NbBundle.getMessage(reportPanel.class, "reportPanel.jEditorPane1.contentType")); // NOI18N jEditorPane1.setEditable(false); jScrollPane1.setViewportView(jEditorPane1); @@ -121,13 +125,19 @@ private void saveReportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FI private void exportReport(String path){ - path = reportUtils.changeExtension(path, ".html"); + String htmlpath = reportUtils.changeExtension(path, ".html"); + String xmlpath = reportUtils.changeExtension(path, ".xml"); try { - FileOutputStream out = new FileOutputStream(path); + FileOutputStream out = new FileOutputStream(htmlpath); out.write(reportHTML.formatted_Report.toString().getBytes()); out.flush(); out.close(); + FileOutputStream xmlout = new FileOutputStream(xmlpath); + XMLOutputter serializer = new XMLOutputter(); + serializer.output(reportXML.xmldoc, xmlout); + xmlout.flush(); + xmlout.close(); jOptionPane1.showMessageDialog(this, "Report has been successfully saved!"); } catch (IOException e) { diff --git a/Report/src/org/sleuthkit/autopsy/report/reportPanelAction.java b/Report/src/org/sleuthkit/autopsy/report/reportPanelAction.java index a329131c0a..9d3dc3f8c5 100644 --- a/Report/src/org/sleuthkit/autopsy/report/reportPanelAction.java +++ b/Report/src/org/sleuthkit/autopsy/report/reportPanelAction.java @@ -97,7 +97,7 @@ public class reportPanelAction { // add the panel to the popup window popUpWindow.add(panel); popUpWindow.pack(); - popUpWindow.setResizable(false); + popUpWindow.setResizable(true); // set the location of the popUp Window on the center of the screen Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize(); @@ -107,7 +107,7 @@ public class reportPanelAction { popUpWindow.setVisible(true); rr.progBarDone(); - // add the command to close the window to the button on the Case Properties form / panel + } } catch (Exception ex) { Log.get(reportFilterAction.class).log(Level.WARNING, "Error displaying " + ACTION_NAME + " window.", ex); diff --git a/Report/src/org/sleuthkit/autopsy/report/reportXML.java b/Report/src/org/sleuthkit/autopsy/report/reportXML.java index 87aeacb691..6a25b35ba8 100644 --- a/Report/src/org/sleuthkit/autopsy/report/reportXML.java +++ b/Report/src/org/sleuthkit/autopsy/report/reportXML.java @@ -19,6 +19,7 @@ import org.jdom.Document.*; import org.jdom.Element; import org.jdom.output.XMLOutputter; import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.Content; @@ -27,8 +28,9 @@ import org.sleuthkit.datamodel.Directory; import org.sleuthkit.datamodel.File; import org.sleuthkit.datamodel.Image; import org.sleuthkit.datamodel.SleuthkitCase; +import org.sleuthkit.datamodel.TskData; public class reportXML { - + public static Document xmldoc = new Document(); public reportXML (HashMap> report, reportFilter rr){ try{ Case currentCase = Case.getCurrentCase(); // get the most updated case @@ -36,8 +38,10 @@ public class reportXML { String caseName = currentCase.getName(); Integer imagecount = currentCase.getImageIDs().length; Integer filesystemcount = currentCase.getRootObjectsCount(); + Integer totalfiles = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG); + Integer totaldirs = skCase.countFsContentType(TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR); Element root = new Element("Case"); - Document xmldoc = new Document(root); + xmldoc = new Document(root); DateFormat datetimeFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss"); Date date = new Date(); @@ -47,9 +51,15 @@ public class reportXML { root.addContent(comment); //Create summary node involving how many of each type Element summary = new Element("Summary"); + if(IngestManager.getDefault().isIngestRunning()) + { + summary.addContent(new Element("Warning").setText("Report was run before ingest services completed!")); + } summary.addContent(new Element("Name").setText(caseName)); summary.addContent(new Element("Total-Images").setText(imagecount.toString())); summary.addContent(new Element("Total-FileSystems").setText(filesystemcount.toString())); + summary.addContent(new Element("Total-Files").setText(totalfiles.toString())); + summary.addContent(new Element("Total-Directories").setText(totaldirs.toString())); root.addContent(summary); //generate the nodes for each of the types so we can use them later Element nodeGen = new Element("General-Information"); @@ -145,7 +155,7 @@ public class reportXML { root.addContent(nodeHash); try { - FileOutputStream out = new FileOutputStream(currentCase.getCaseDirectory()+"/Temp/" + caseName + "-" + datenotime + ".xml"); + FileOutputStream out = new FileOutputStream(currentCase.getCaseDirectory()+"/Reports/" + caseName + "-" + datenotime + ".xml"); XMLOutputter serializer = new XMLOutputter(); serializer.output(xmldoc, out); out.flush();