mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
Merge branch 'master' of https://github.com/sleuthkit/autopsy
This commit is contained in:
commit
b8a67ae7db
@ -48,7 +48,7 @@ final class AddImageVisualPanel1 extends JPanel {
|
||||
static final String encaseDesc = "Encase Images (*.e01)";
|
||||
static GeneralFilter encaseFilter = new GeneralFilter(encaseExt, encaseDesc);
|
||||
static final List<String> allExt = new ArrayList<String>();
|
||||
{
|
||||
static {
|
||||
allExt.addAll(rawExt);
|
||||
allExt.addAll(encaseExt);
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ public class ImageFilePanel extends ContentTypePanel implements DocumentListener
|
||||
fc.setDragEnabled(false);
|
||||
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||
fc.setMultiSelectionEnabled(false);
|
||||
fc.addChoosableFileFilter(AddImageVisualPanel1.allFilter);
|
||||
fc.addChoosableFileFilter(AddImageVisualPanel1.rawFilter);
|
||||
fc.addChoosableFileFilter(AddImageVisualPanel1.encaseFilter);
|
||||
fc.setFileFilter(AddImageVisualPanel1.allFilter);
|
||||
|
52
Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.form
Executable file
52
Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.form
Executable file
@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<NonVisualComponents>
|
||||
<Container class="javax.swing.JPopupMenu" name="jPopupMenu1">
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
|
||||
<Property name="useNullLayout" type="boolean" value="true"/>
|
||||
</Layout>
|
||||
</Container>
|
||||
</NonVisualComponents>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane2" alignment="0" pref="400" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jScrollPane2" alignment="0" pref="300" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
|
||||
<AuxValues>
|
||||
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JTextPane" name="jTextPane1">
|
||||
<Properties>
|
||||
<Property name="editable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
189
Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java
Executable file
189
Core/src/org/sleuthkit/autopsy/contentviewers/Metadata.java
Executable file
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> 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.contentviewers;
|
||||
|
||||
import java.awt.Component;
|
||||
import javax.swing.JTextPane;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Shows file metadata as a list to make it easy to copy and paste.
|
||||
* Typically shows the same data that can also be found in the ResultViewer table,
|
||||
* just a different order and allows the full path to be visible in the bottom area.
|
||||
*/
|
||||
@ServiceProvider(service = DataContentViewer.class, position = 3)
|
||||
public class Metadata extends javax.swing.JPanel implements DataContentViewer
|
||||
{
|
||||
/**
|
||||
* Creates new form Metadata
|
||||
*/
|
||||
public Metadata() {
|
||||
initComponents();
|
||||
customizeComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
jPopupMenu1 = new javax.swing.JPopupMenu();
|
||||
jScrollPane2 = new javax.swing.JScrollPane();
|
||||
jTextPane1 = new javax.swing.JTextPane();
|
||||
|
||||
jTextPane1.setEditable(false);
|
||||
jScrollPane2.setViewportView(jTextPane1);
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 300, Short.MAX_VALUE)
|
||||
);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JPopupMenu jPopupMenu1;
|
||||
private javax.swing.JScrollPane jScrollPane2;
|
||||
private javax.swing.JTextPane jTextPane1;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
private void customizeComponents(){
|
||||
/*
|
||||
jTextPane1.setComponentPopupMenu(rightClickMenu);
|
||||
ActionListener actList = new ActionListener(){
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e){
|
||||
JMenuItem jmi = (JMenuItem) e.getSource();
|
||||
if(jmi.equals(copyMenuItem))
|
||||
outputViewPane.copy();
|
||||
else if(jmi.equals(selectAllMenuItem))
|
||||
outputViewPane.selectAll();
|
||||
}
|
||||
};
|
||||
copyMenuItem.addActionListener(actList);
|
||||
selectAllMenuItem.addActionListener(actList);
|
||||
*/
|
||||
|
||||
Utilities.configureTextPaneAsHtml(jTextPane1);
|
||||
}
|
||||
|
||||
private void setText(String str) {
|
||||
jTextPane1.setText("<html><body>" + str + "</body></html>");
|
||||
}
|
||||
|
||||
private void startTable(StringBuilder sb) {
|
||||
sb.append("<table>");
|
||||
}
|
||||
|
||||
private void endTable(StringBuilder sb) {
|
||||
sb.append("</table>");
|
||||
}
|
||||
|
||||
private void addRow(StringBuilder sb, String key, String value) {
|
||||
sb.append("<tr><td>");
|
||||
sb.append(key);
|
||||
sb.append("</td><td>");
|
||||
sb.append(value);
|
||||
sb.append("</td></tr>");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNode(Node node) {
|
||||
AbstractFile file = node.getLookup().lookup(AbstractFile.class);
|
||||
if (file == null) {
|
||||
setText("Non-file passed in");
|
||||
return;
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
startTable(sb);
|
||||
|
||||
try {
|
||||
addRow(sb, "Name", file.getUniquePath());
|
||||
} catch (TskCoreException ex) {
|
||||
addRow(sb, "Name", file.getParentPath() + "/" + file.getName());
|
||||
}
|
||||
|
||||
addRow(sb, "Modified", file.getMtimeAsDate());
|
||||
addRow(sb, "Accessed", file.getAtimeAsDate());
|
||||
addRow(sb, "Created", file.getCrtimeAsDate());
|
||||
addRow(sb, "Changed", file.getCtimeAsDate());
|
||||
|
||||
String md5 = file.getMd5Hash();
|
||||
if (md5 == null) {
|
||||
md5 = "Not calculated";
|
||||
}
|
||||
addRow(sb, "MD5", md5);
|
||||
|
||||
endTable(sb);
|
||||
setText(sb.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "Metadata";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getToolTip() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataContentViewer createInstance() {
|
||||
return new Metadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Component getComponent() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetComponent() {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported(Node node) {
|
||||
AbstractFile file = node.getLookup().lookup(AbstractFile.class);
|
||||
if (file == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int isPreferred(Node node, boolean isSupported) {
|
||||
return 1;
|
||||
}
|
||||
}
|
49
Core/src/org/sleuthkit/autopsy/contentviewers/Utilities.java
Executable file
49
Core/src/org/sleuthkit/autopsy/contentviewers/Utilities.java
Executable file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2013 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> 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.contentviewers;
|
||||
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
import javax.swing.text.html.StyleSheet;
|
||||
|
||||
/**
|
||||
*
|
||||
* Methods common to ContentViewers.
|
||||
*/
|
||||
public class Utilities {
|
||||
|
||||
public static void configureTextPaneAsHtml(JTextPane pane) {
|
||||
pane.setContentType("text/html;charset=UTF-8");
|
||||
HTMLEditorKit kit = new HTMLEditorKit();
|
||||
pane.setEditorKit(kit);
|
||||
StyleSheet styleSheet = kit.getStyleSheet();
|
||||
/* I tried to play around with inheritence on font-size and it didn't
|
||||
* always work. Defined all of the basics just in case.
|
||||
* @@@ IngestInboxViewer also defines styles similar to this. Consider
|
||||
* a method that sets consistent styles for all viewers and takes font
|
||||
* size as an argument.
|
||||
*/
|
||||
styleSheet.addRule("body {font-family:Arial;font-size:14pt;}");
|
||||
styleSheet.addRule("p {font-family:Arial;font-size:14pt;}");
|
||||
styleSheet.addRule("li {font-family:Arial;font-size:14pt;}");
|
||||
styleSheet.addRule("td {font-family:Arial;font-size:14pt;overflow:hidden;padding-right:5px;padding-left:5px;}");
|
||||
styleSheet.addRule("th {font-family:Arial;font-size:14pt;overflow:hidden;padding-right:5px;padding-left:5px;font-weight:bold;}");
|
||||
styleSheet.addRule("p {font-family:Arial;font-size:14pt;}");
|
||||
}
|
||||
}
|
@ -31,11 +31,10 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.text.html.HTMLEditorKit;
|
||||
import javax.swing.text.html.StyleSheet;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.contentviewers.Utilities;
|
||||
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
|
||||
import org.sleuthkit.autopsy.datamodel.ArtifactStringContent;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
@ -245,22 +244,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
|
||||
copyMenuItem.addActionListener(actList);
|
||||
selectAllMenuItem.addActionListener(actList);
|
||||
|
||||
outputViewPane.setContentType("text/html;charset=UTF-8");
|
||||
HTMLEditorKit kit = new HTMLEditorKit();
|
||||
outputViewPane.setEditorKit(kit);
|
||||
StyleSheet styleSheet = kit.getStyleSheet();
|
||||
/* I tried to play around with inheritence on font-size and it didn't
|
||||
* always work. Defined all of the basics just in case.
|
||||
* @@@ IngestInboxViewer also defines styles similar to this. Consider
|
||||
* a method that sets consistent styles for all viewers and takes font
|
||||
* size as an argument.
|
||||
*/
|
||||
styleSheet.addRule("body {font-family:Arial;font-size:14pt;}");
|
||||
styleSheet.addRule("p {font-family:Arial;font-size:14pt;}");
|
||||
styleSheet.addRule("li {font-family:Arial;font-size:14pt;}");
|
||||
styleSheet.addRule("td {font-family:Arial;font-size:14pt;overflow:hidden;padding-right:5px;padding-left:5px;}");
|
||||
styleSheet.addRule("th {font-family:Arial;font-size:14pt;overflow:hidden;padding-right:5px;padding-left:5px;font-weight:bold;}");
|
||||
styleSheet.addRule("p {font-family:Arial;font-size:14pt;}");
|
||||
Utilities.configureTextPaneAsHtml(outputViewPane);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -304,7 +288,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "Result View";
|
||||
return "Results";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -390,7 +390,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "Hex View";
|
||||
return "Hex";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -162,7 +162,7 @@ public class DataContentViewerMedia extends javax.swing.JPanel implements DataCo
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "Media View";
|
||||
return "Media";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -443,7 +443,7 @@ public class DataContentViewerString extends javax.swing.JPanel implements DataC
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "String View";
|
||||
return "Strings";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -385,7 +385,7 @@ public class DataResultViewerTable extends AbstractDataResultViewer {
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "Table View";
|
||||
return "Table";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -353,7 +353,7 @@ public final class DataResultViewerThumbnail extends AbstractDataResultViewer {
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "Thumbnail View";
|
||||
return "Thumbnail";
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -378,7 +378,9 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Return the types of mark up sources that this viewer knows about.
|
||||
* Different sources will markup the text in different ways.
|
||||
*
|
||||
* @return currently available sources on the panel
|
||||
*/
|
||||
public List<MarkupSource> getSources() {
|
||||
@ -390,7 +392,7 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get the source selected in the combo box
|
||||
* @return currently selected Source
|
||||
*/
|
||||
public MarkupSource getSelectedSource() {
|
||||
@ -652,7 +654,8 @@ class ExtractedContentPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and sets new markup. Updates GUI in GUI thread and gets markup in
|
||||
* Gets and sets new markup (i.e. based on user choose keyword hits or pure text).
|
||||
* Updates GUI in GUI thread and gets markup in
|
||||
* background thread. To be invoked from GUI thread only.
|
||||
*/
|
||||
private void setMarkup(MarkupSource source) {
|
||||
|
@ -81,20 +81,23 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
currentNode = selectedNode;
|
||||
}
|
||||
|
||||
// sources are custom markup from the node (if available) and default
|
||||
// markup is fetched from solr
|
||||
/* Sources contain implementations that will markup the text
|
||||
* in different ways. The original behavior for this was a source
|
||||
* for the text markedup by SOLR and another that just displayed
|
||||
* raw text.
|
||||
*/
|
||||
final List<MarkupSource> sources = new ArrayList<MarkupSource>();
|
||||
|
||||
//add additional registered sources for this node
|
||||
sources.addAll(selectedNode.getLookup().lookupAll(MarkupSource.class));
|
||||
|
||||
if (!solrHasContent(selectedNode)) {
|
||||
//currentNode = null;
|
||||
//resetComponent();
|
||||
// first source will be the default displayed
|
||||
|
||||
// if it doesn't have any SOLR content, then we won't add more sources
|
||||
if (solrHasContent(selectedNode) == false) {
|
||||
setPanel(sources);
|
||||
return;
|
||||
}
|
||||
|
||||
Content content = selectedNode.getLookup().lookup(Content.class);
|
||||
if (content == null) {
|
||||
return;
|
||||
@ -103,6 +106,8 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
//add to page tracking if not there yet
|
||||
final long contentID = content.getId();
|
||||
|
||||
// make a new source for the raw content
|
||||
// @@@ BC: Why isn't this its own class like Highlight?
|
||||
final MarkupSource newSource = new MarkupSource() {
|
||||
private boolean inited = false;
|
||||
private int numPages = 0;
|
||||
@ -259,7 +264,7 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return "Text View";
|
||||
return "Text";
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -289,6 +294,8 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
public void resetComponent() {
|
||||
setPanel(new ArrayList<MarkupSource>());
|
||||
panel.resetDisplay();
|
||||
currentNode = null;
|
||||
currentSource = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -460,6 +467,11 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
MarkupSource source = panel.getSelectedSource();
|
||||
if (source == null) {
|
||||
// reset
|
||||
panel.updateControls(null);
|
||||
return;
|
||||
}
|
||||
final boolean hasNextItem = source.hasNextItem();
|
||||
final boolean hasNextPage = source.hasNextPage();
|
||||
int indexVal = 0;
|
||||
@ -552,6 +564,12 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
}
|
||||
|
||||
private void nextPage() {
|
||||
// we should never have gotten here -- reset
|
||||
if (currentSource == null) {
|
||||
panel.updateControls(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentSource.hasNextPage()) {
|
||||
currentSource.nextPage();
|
||||
|
||||
@ -579,6 +597,12 @@ public class ExtractedContentViewer implements DataContentViewer {
|
||||
}
|
||||
|
||||
private void previousPage() {
|
||||
// reset, we should have never gotten here if null
|
||||
if (currentSource == null) {
|
||||
panel.updateControls(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentSource.hasPreviousPage()) {
|
||||
currentSource.previousPage();
|
||||
|
||||
|
@ -46,7 +46,7 @@ class HighlightedMatchesSource implements MarkupSource, HighlightLookup {
|
||||
private static final String HIGHLIGHT_PRE = "<span style='background:yellow'>";
|
||||
private static final String HIGHLIGHT_POST = "</span>";
|
||||
private static final String ANCHOR_PREFIX = HighlightedMatchesSource.class.getName() + "_";
|
||||
private static final String NO_MATCHES = "<span style='background:red'>No matches in content.</span>";
|
||||
private static final String NO_MATCHES = "<span style='background:yellow'>There were no keyword hits on this page. <br />Advance to another page for hits or choose Extracted Text to view original text..</span>";
|
||||
private Content content;
|
||||
private String keywordHitQuery;
|
||||
private Server solrServer;
|
||||
|
@ -21,8 +21,10 @@ package org.sleuthkit.autopsy.keywordsearch;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
* Interface to provide HTML markup (to be displayed in ExtractedContentViewer)
|
||||
* in a Node's lookup
|
||||
* Interface to provide HTML text to display in ExtractedContentViewer.
|
||||
* There is a SOLR implementaiton of this that interfaces with SOLR to
|
||||
* highlight the keyword hits and a version that does not do markup
|
||||
* so that you can simply view the stored text.
|
||||
*/
|
||||
public interface MarkupSource {
|
||||
|
||||
|
@ -25,7 +25,6 @@ package org.sleuthkit.autopsy.recentactivity;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
@ -39,7 +38,7 @@ abstract public class Extract extends IngestModuleDataSource{
|
||||
protected Case currentCase = Case.getCurrentCase(); // get the most updated case
|
||||
protected SleuthkitCase tskCase = currentCase.getSleuthkitCase();
|
||||
public final Logger logger = Logger.getLogger(this.getClass().getName());
|
||||
protected final ArrayList<String> errorMessages = new ArrayList<String>();
|
||||
protected final ArrayList<String> errorMessages = new ArrayList<>();
|
||||
protected String moduleName = "";
|
||||
|
||||
//hide public constructor to prevent from instantiation by ingest module loader
|
||||
@ -47,10 +46,23 @@ abstract public class Extract extends IngestModuleDataSource{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a List of string error messages from the inheriting class
|
||||
* @return errorMessages returns all error messages logged
|
||||
*/
|
||||
List<String> getErrorMessages() {
|
||||
return errorMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a string to the error message list
|
||||
*
|
||||
* @param message is an error message represented as a string
|
||||
*/
|
||||
protected void addErrorMessage(String message) {
|
||||
errorMessages.add(message);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Generic method for adding a blackboard artifact to the blackboard
|
||||
@ -120,25 +132,10 @@ abstract public class Extract extends IngestModuleDataSource{
|
||||
|
||||
return list;
|
||||
}
|
||||
/**
|
||||
* Returns a List of string error messages from the inheriting class
|
||||
* @return errorMessages returns all error messages logged
|
||||
*/
|
||||
|
||||
|
||||
|
||||
public ArrayList<String> getErrorMessage() {
|
||||
return errorMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a string to the error message list
|
||||
*
|
||||
* @param message is an error message represented as a string
|
||||
*/
|
||||
public void addErrorMessage(String message) {
|
||||
errorMessages.add(message);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Returns the name of the inheriting class
|
||||
* @return Gets the moduleName set in the moduleName data member
|
||||
*/
|
||||
|
@ -2,7 +2,7 @@
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2012 Basis Technology Corp.
|
||||
* Copyright 2012-2013 Basis Technology Corp.
|
||||
*
|
||||
* Copyright 2012 42six Solutions.
|
||||
* Contact: aebadirad <at> 42six <dot> com
|
||||
@ -35,12 +35,10 @@ import java.io.Writer;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Scanner;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@ -52,7 +50,6 @@ import org.sleuthkit.autopsy.coreutils.EscapeUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.JLNK;
|
||||
import org.sleuthkit.autopsy.coreutils.JLnkParser;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||
import org.sleuthkit.autopsy.datamodel.KeyValue;
|
||||
import org.sleuthkit.autopsy.ingest.IngestDataSourceWorkerController;
|
||||
import org.sleuthkit.autopsy.ingest.IngestServices;
|
||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||
@ -61,7 +58,6 @@ import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.ingest.PipelineContext;
|
||||
import org.sleuthkit.autopsy.ingest.IngestModuleDataSource;
|
||||
@ -69,24 +65,16 @@ import org.sleuthkit.autopsy.ingest.IngestModuleInit;
|
||||
import org.sleuthkit.datamodel.*;
|
||||
|
||||
public class ExtractIE extends Extract {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ExtractIE.class.getName());
|
||||
private IngestServices services;
|
||||
private String recentQuery = "select * from `tsk_files` where parent_path LIKE '%/Recent%' and name LIKE '%.lnk'";
|
||||
//sleauthkit db handle
|
||||
SleuthkitCase tskCase;
|
||||
|
||||
//paths set in init()
|
||||
private String PASCO_RESULTS_PATH;
|
||||
private String moduleTempResultsDir;
|
||||
private String PASCO_LIB_PATH;
|
||||
private String JAVA_PATH;
|
||||
//Results List to be referenced/used outside the class
|
||||
public ArrayList<HashMap<String, Object>> PASCO_RESULTS_LIST = new ArrayList<HashMap<String, Object>>();
|
||||
|
||||
// List of Pasco result files for this data source
|
||||
private List<String> pascoResults;
|
||||
//Look Up Table that holds Pasco2 results
|
||||
private HashMap<String, Object> PASCO_RESULTS_LUT;
|
||||
private KeyValue IE_PASCO_LUT = new KeyValue(BrowserType.IE.name(), BrowserType.IE.getType());
|
||||
public LinkedHashMap<String, Object> IE_OBJ;
|
||||
boolean pascoFound = false;
|
||||
final public static String MODULE_VERSION = "1.0";
|
||||
private static final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
|
||||
@ -96,6 +84,8 @@ public class ExtractIE extends Extract {
|
||||
//hide public constructor to prevent from instantiation by ingest module loader
|
||||
ExtractIE() {
|
||||
moduleName = "Internet Explorer";
|
||||
moduleTempResultsDir = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), "IE") + File.separator + "results";
|
||||
JAVA_PATH = PlatformUtil.getJavaPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -106,11 +96,52 @@ public class ExtractIE extends Extract {
|
||||
|
||||
@Override
|
||||
public void process(PipelineContext<IngestModuleDataSource>pipelineContext, Content dataSource, IngestDataSourceWorkerController controller) {
|
||||
this.getHistory(dataSource, controller);
|
||||
this.getBookmark(dataSource, controller);
|
||||
this.getCookie(dataSource, controller);
|
||||
this.getRecentDocuments(dataSource, controller);
|
||||
this.parsePascoResults(pascoResults);
|
||||
/* @@@ BC: All of these try / catches are added because the exception
|
||||
* handing in here isn't the best. We were losing results before because
|
||||
* cookies was throwing an exceptionb ecause of an invalid URL and we
|
||||
* skipped the rest of the data types. Need to push this eror handling
|
||||
* further down though.
|
||||
*/
|
||||
|
||||
try {
|
||||
this.extractAndRunPasco(dataSource, controller);
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Error extracting IE index.dat files", e);
|
||||
addErrorMessage("Error extracting and analyzing IE index.dat files");
|
||||
}
|
||||
|
||||
try {
|
||||
this.getBookmark(dataSource, controller);
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Error parsing IE bookmarks", e);
|
||||
addErrorMessage("Error parsing IE bookmarks");
|
||||
}
|
||||
|
||||
try {
|
||||
this.getCookie(dataSource, controller);
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Error parsing IE cookies", e);
|
||||
addErrorMessage("Error parsing IE Cookies");
|
||||
}
|
||||
|
||||
try {
|
||||
this.getRecentDocuments(dataSource, controller);
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Error parsing IE Recent Docs", e);
|
||||
addErrorMessage("Error parsing IE Recent Documents");
|
||||
}
|
||||
|
||||
try {
|
||||
this.parsePascoResults(pascoResults);
|
||||
}
|
||||
catch (Exception e) {
|
||||
logger.log(Level.SEVERE, "Error parsing IE History", e);
|
||||
addErrorMessage("Error parsing IE History");
|
||||
}
|
||||
}
|
||||
|
||||
//Favorites section
|
||||
@ -273,20 +304,11 @@ public class ExtractIE extends Extract {
|
||||
services.fireModuleDataEvent(new ModuleDataEvent("Recent Activity", BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT));
|
||||
}
|
||||
|
||||
//@Override
|
||||
public KeyValue getRecentActivity() {
|
||||
return IE_PASCO_LUT;
|
||||
}
|
||||
|
||||
private void getHistory(Content dataSource, IngestDataSourceWorkerController controller) {
|
||||
currentCase = Case.getCurrentCase();
|
||||
tskCase = currentCase.getSleuthkitCase();
|
||||
|
||||
PASCO_RESULTS_PATH = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), "IE") + File.separator + "results";
|
||||
JAVA_PATH = PlatformUtil.getJavaPath();
|
||||
private void extractAndRunPasco(Content dataSource, IngestDataSourceWorkerController controller) {
|
||||
pascoResults = new ArrayList<String>();
|
||||
|
||||
logger.log(Level.INFO, "Pasco results path: " + PASCO_RESULTS_PATH);
|
||||
logger.log(Level.INFO, "Pasco results path: " + moduleTempResultsDir);
|
||||
|
||||
final File pascoRoot = InstalledFileLocator.getDefault().locate("pasco2", ExtractIE.class.getPackage().getName(), false);
|
||||
if (pascoRoot == null) {
|
||||
@ -303,7 +325,7 @@ public class ExtractIE extends Extract {
|
||||
PASCO_LIB_PATH = pascoHome + File.separator + "pasco2.jar" + File.pathSeparator
|
||||
+ pascoHome + File.separator + "*";
|
||||
|
||||
File resultsDir = new File(PASCO_RESULTS_PATH);
|
||||
File resultsDir = new File(moduleTempResultsDir);
|
||||
resultsDir.mkdirs();
|
||||
|
||||
|
||||
@ -365,7 +387,7 @@ public class ExtractIE extends Extract {
|
||||
|
||||
Writer writer = null;
|
||||
try {
|
||||
final String pascoOutFile = PASCO_RESULTS_PATH + File.separator + filename;
|
||||
final String pascoOutFile = moduleTempResultsDir + File.separator + filename;
|
||||
logger.log(Level.INFO, "Writing pasco results to: " + pascoOutFile);
|
||||
writer = new FileWriter(pascoOutFile);
|
||||
execPasco = new ExecUtil();
|
||||
@ -400,11 +422,7 @@ public class ExtractIE extends Extract {
|
||||
}
|
||||
// First thing we want to do is check to make sure the results directory
|
||||
// is not empty.
|
||||
File rFile = new File(PASCO_RESULTS_PATH);
|
||||
|
||||
|
||||
//Let's make sure our list and lut are empty.
|
||||
//PASCO_RESULTS_LIST.clear();
|
||||
File rFile = new File(moduleTempResultsDir);
|
||||
|
||||
if (rFile.exists()) {
|
||||
//Give me a list of pasco results in that directory
|
||||
@ -418,7 +436,6 @@ public class ExtractIE extends Extract {
|
||||
continue;
|
||||
}
|
||||
long artObjId = Long.parseLong(fileName.substring(fileName.indexOf(".") + 1, fileName.lastIndexOf(".")));
|
||||
//bbartname = bbartname.substring(0, 4);
|
||||
|
||||
// Make sure the file the is not empty or the Scanner will
|
||||
// throw a "No Line found" Exception
|
||||
@ -429,29 +446,28 @@ public class ExtractIE extends Extract {
|
||||
fileScanner.nextLine();
|
||||
fileScanner.nextLine();
|
||||
fileScanner.nextLine();
|
||||
// long inIndexId = 0;
|
||||
|
||||
while (fileScanner.hasNext()) {
|
||||
//long bbartId = Long.parseLong(bbartname + inIndexId++);
|
||||
|
||||
String line = fileScanner.nextLine();
|
||||
|
||||
//Need to change this pattern a bit because there might
|
||||
//be instances were "V" might not apply.
|
||||
String pattern = "(?)URL(\\s)(V|\\:)";
|
||||
Pattern p = Pattern.compile(pattern);
|
||||
Matcher m = p.matcher(line);
|
||||
if (m.find()) {
|
||||
if (line.startsWith("URL")) {
|
||||
String[] lineBuff = line.split("\\t");
|
||||
PASCO_RESULTS_LUT = new HashMap<String, Object>();
|
||||
String url[] = lineBuff[1].split("@", 2);
|
||||
|
||||
if (lineBuff.length < 4) {
|
||||
// @@@ Could log a message here
|
||||
continue;
|
||||
}
|
||||
|
||||
String ddtime = lineBuff[2];
|
||||
String actime = lineBuff[3];
|
||||
Long ftime = (long) 0;
|
||||
String user = "";
|
||||
String realurl = "";
|
||||
String domain = "";
|
||||
if (url.length > 1) {
|
||||
|
||||
if (lineBuff[1].contains("@")) {
|
||||
String url[] = lineBuff[1].split("@", 2);
|
||||
user = url[0];
|
||||
user = user.replace("Visited:", "");
|
||||
user = user.replace(":Host:", "");
|
||||
@ -462,12 +478,19 @@ public class ExtractIE extends Extract {
|
||||
realurl = realurl.replaceAll(":(.*?):", "");
|
||||
realurl = realurl.replace(":Host:", "");
|
||||
realurl = realurl.trim();
|
||||
domain = Util.extractDomain(realurl);
|
||||
}
|
||||
else {
|
||||
user = "";
|
||||
realurl = lineBuff[1].trim();
|
||||
}
|
||||
|
||||
domain = Util.extractDomain(realurl);
|
||||
|
||||
if (!ddtime.isEmpty()) {
|
||||
ddtime = ddtime.replace("T", " ");
|
||||
ddtime = ddtime.substring(ddtime.length() - 5);
|
||||
}
|
||||
|
||||
if (!actime.isEmpty()) {
|
||||
try {
|
||||
Long epochtime = dateFormatter.parse(actime).getTime();
|
||||
@ -478,7 +501,6 @@ public class ExtractIE extends Extract {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Need to fix this so we have the right obj_id
|
||||
try {
|
||||
BlackboardArtifact bbart = tskCase.getContentById(artObjId).newArtifact(ARTIFACT_TYPE.TSK_WEB_HISTORY);
|
||||
Collection<BlackboardAttribute> bbattributes = new ArrayList<BlackboardAttribute>();
|
||||
@ -497,27 +519,19 @@ public class ExtractIE extends Extract {
|
||||
bbart.addAttributes(bbattributes);
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error writing Internet Explorer web history artifact to the blackboard.", ex);
|
||||
}
|
||||
|
||||
//KeyValueThing
|
||||
//This will be redundant in terms IE.name() because of
|
||||
//the way they implemented KeyValueThing
|
||||
IE_OBJ = new LinkedHashMap<String, Object>();
|
||||
IE_OBJ.put(BrowserType.IE.name(), PASCO_RESULTS_LUT);
|
||||
IE_PASCO_LUT.addMap(IE_OBJ);
|
||||
|
||||
PASCO_RESULTS_LIST.add(PASCO_RESULTS_LUT);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// @@@ Log that we didn't parse this
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} catch (FileNotFoundException ex) {
|
||||
logger.log(Level.WARNING, "Unable to find the Pasco file at " + file.getPath(), ex);
|
||||
}
|
||||
}
|
||||
//TODO: Fix Delete issue
|
||||
boolean bDelete = file.delete();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -532,8 +546,8 @@ public class ExtractIE extends Extract {
|
||||
@Override
|
||||
public void complete() {
|
||||
// Delete all the results when complete
|
||||
for (String file : pascoResults) {
|
||||
String filePath = PASCO_RESULTS_PATH + File.separator + file;
|
||||
/*for (String file : pascoResults) {
|
||||
String filePath = moduleTempResultsDir + File.separator + file;
|
||||
try {
|
||||
File f = new File(filePath);
|
||||
if (f.exists() && f.canWrite()) {
|
||||
@ -545,6 +559,7 @@ public class ExtractIE extends Extract {
|
||||
logger.log(Level.WARNING, "Incorrect permission to delete file " + filePath, ex);
|
||||
}
|
||||
}
|
||||
*/
|
||||
pascoResults.clear();
|
||||
logger.info("Internet Explorer extract has completed.");
|
||||
}
|
||||
@ -556,7 +571,6 @@ public class ExtractIE extends Extract {
|
||||
execPasco = null;
|
||||
}
|
||||
|
||||
|
||||
//call regular cleanup from complete() method
|
||||
complete();
|
||||
}
|
||||
@ -570,4 +584,4 @@ public class ExtractIE extends Extract {
|
||||
public boolean hasBackgroundJobsRunning() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@ -71,11 +71,13 @@ public final class RAImageIngestModule extends IngestModuleDataSource {
|
||||
logger.log(Level.INFO, "Recent Activity has been canceled, quitting before {0}", module.getName());
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
module.process(pipelineContext, dataSource, controller);
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, "Exception occurred in " + module.getName(), ex);
|
||||
subCompleted.append(module.getName()).append(" failed - see log for details <br>");
|
||||
errors.add(module.getName() + "had errors -- see log");
|
||||
}
|
||||
controller.progress(i + 1);
|
||||
errors.addAll(module.getErrorMessages());
|
||||
@ -84,7 +86,9 @@ public final class RAImageIngestModule extends IngestModuleDataSource {
|
||||
// create the final message for inbox
|
||||
StringBuilder errorMessage = new StringBuilder();
|
||||
String errorMsgSubject;
|
||||
if (!errors.isEmpty()) {
|
||||
MessageType msgLevel = MessageType.INFO;
|
||||
if (errors.isEmpty() == false) {
|
||||
msgLevel = MessageType.ERROR;
|
||||
errorMessage.append("<p>Errors encountered during analysis: <ul>\n");
|
||||
for (String msg : errors) {
|
||||
errorMessage.append("<li>").append(msg).append("</li>\n");
|
||||
@ -100,7 +104,7 @@ public final class RAImageIngestModule extends IngestModuleDataSource {
|
||||
errorMessage.append("<p>No errors encountered.</p>");
|
||||
errorMsgSubject = "No errors reported";
|
||||
}
|
||||
final IngestMessage msg = IngestMessage.createMessage(++messageId, MessageType.INFO, this, "Finished " + dataSource.getName()+ " - " + errorMsgSubject, errorMessage.toString());
|
||||
final IngestMessage msg = IngestMessage.createMessage(++messageId, msgLevel, this, "Finished " + dataSource.getName()+ " - " + errorMsgSubject, errorMessage.toString());
|
||||
services.postMessage(msg);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user