7084 handle merge conflicts

This commit is contained in:
William Schaefer 2020-12-28 11:08:25 -05:00
commit 6ff945c981
41 changed files with 1322 additions and 531 deletions

View File

@ -89,8 +89,15 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
return; return;
} }
if (CURRENT_CASE == Case.Events.valueOf(evt.getPropertyName())) { // Check whether we have a case open or case close event.
refresh(); if ((CURRENT_CASE == Case.Events.valueOf(evt.getPropertyName()))) {
if (evt.getNewValue() != null) {
// Case open
refresh();
} else {
// Case close
reset();
}
} }
}); });
} }
@ -124,7 +131,7 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
*/ */
private void refresh() { private void refresh() {
try { try {
if (Case.isCaseOpen()) { if (Case.isCaseOpen()) { // Note - this will generally return true when handling a case close event
SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase();
this.ingestJobs = skCase.getIngestJobs(); this.ingestJobs = skCase.getIngestJobs();
setDataSource(selectedDataSource); setDataSource(selectedDataSource);
@ -138,6 +145,14 @@ public final class IngestJobInfoPanel extends javax.swing.JPanel {
JOptionPane.showMessageDialog(this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE); JOptionPane.showMessageDialog(this, Bundle.IngestJobInfoPanel_loadIngestJob_error_text(), Bundle.IngestJobInfoPanel_loadIngestJob_error_title(), JOptionPane.ERROR_MESSAGE);
} }
} }
/**
* Reset the panel.
*/
private void reset() {
this.ingestJobs = new ArrayList<>();
setDataSource(null);
}
@Messages({"IngestJobInfoPanel.IngestJobTableModel.StartTime.header=Start Time", @Messages({"IngestJobInfoPanel.IngestJobTableModel.StartTime.header=Start Time",
"IngestJobInfoPanel.IngestJobTableModel.EndTime.header=End Time", "IngestJobInfoPanel.IngestJobTableModel.EndTime.header=End Time",

View File

@ -52,11 +52,9 @@ import javax.swing.JPanel;
import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.TableModel; import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter; import javax.swing.table.TableRowSorter;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTimeZone; import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime; import org.joda.time.LocalDateTime;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
@ -78,7 +76,6 @@ import org.sleuthkit.datamodel.TskException;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
/** /**
* View correlation results from other cases * View correlation results from other cases
@ -469,16 +466,11 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
if (bbArtifact != null && CentralRepository.isEnabled()) { if (bbArtifact != null && CentralRepository.isEnabled()) {
ret.addAll(CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact)); ret.addAll(CorrelationAttributeUtil.makeCorrAttrsForCorrelation(bbArtifact));
} }
boolean isSupported = false;
try {
isSupported = this.file != null && this.file.getSize() > 0 && isDownloadParentSupported(node);
} catch (TskCoreException ex) {
LOGGER.log(Level.WARNING, ex.getMessage(), ex);
}
// we can correlate based on the MD5 if it is enabled // we can correlate based on the MD5 if it is enabled
if (isSupported && CentralRepository.isEnabled()) { if (this.file != null && CentralRepository.isEnabled() && this.file.getSize() > 0) {
try { try {
List<CorrelationAttributeInstance.Type> artifactTypes = CentralRepository.getInstance().getDefinedCorrelationTypes(); List<CorrelationAttributeInstance.Type> artifactTypes = CentralRepository.getInstance().getDefinedCorrelationTypes();
String md5 = this.file.getMd5Hash(); String md5 = this.file.getMd5Hash();
if (md5 != null && !md5.isEmpty() && null != artifactTypes && !artifactTypes.isEmpty()) { if (md5 != null && !md5.isEmpty() && null != artifactTypes && !artifactTypes.isEmpty()) {
@ -506,7 +498,7 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
LOGGER.log(Level.SEVERE, "Error connecting to DB", ex); // NON-NLS LOGGER.log(Level.SEVERE, "Error connecting to DB", ex); // NON-NLS
} }
// If EamDb not enabled, get the Files default correlation type to allow Other Occurances to be enabled. // If EamDb not enabled, get the Files default correlation type to allow Other Occurances to be enabled.
} else if (isSupported) { } else if (this.file != null && this.file.getSize() > 0) {
String md5 = this.file.getMd5Hash(); String md5 = this.file.getMd5Hash();
if (md5 != null && !md5.isEmpty()) { if (md5 != null && !md5.isEmpty()) {
try { try {
@ -525,37 +517,8 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
} }
} }
} }
return ret;
}
/** return ret;
* Private helper method to check if the node is an TSK_WEB_DOWNLOAD or
* TSK_WEB_CACHE artifact and if it is, if the file reflects the parent file
* or the downloaded file.
*
* @param node The node to check support for.
*
* @return False if the node is for a Web Cache or a Web Download artifact,
* and that artifact's content file is it's parent.
*
* @throws TskCoreException Unable to retrieve the parent of the artifact in
* this node.
*/
private boolean isDownloadParentSupported(Node node) throws TskCoreException {
if (node instanceof BlackboardArtifactNode) {
BlackboardArtifact theArtifact = ((BlackboardArtifactNode) node).getArtifact();
try {
//disable the content viewer when a download or cached file does not exist instead of displaying its parent
if ((theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& this.file.getId() == theArtifact.getParent().getId()) {
return false;
}
} catch (TskCoreException ex) {
throw new TskCoreException(String.format("Error getting parent of artifact with type %s and objID = %d can not confirm content with name %s and objId = %d is not the parent. Other occurences will not correlate on the file.", theArtifact.getArtifactTypeName(), theArtifact.getObjectID(), this.file.getName(), this.file.getId()), ex);
}
}
return true;
} }
@Messages({"DataContentViewerOtherCases.earliestCaseNotAvailable= Not Enabled."}) @Messages({"DataContentViewerOtherCases.earliestCaseNotAvailable= Not Enabled."})
@ -738,16 +701,11 @@ public class DataContentViewerOtherCases extends JPanel implements DataContentVi
this.file = this.getAbstractFileFromNode(node); this.file = this.getAbstractFileFromNode(node);
if (CentralRepository.isEnabled()) { if (CentralRepository.isEnabled()) {
return !getCorrelationAttributesFromNode(node).isEmpty(); return !getCorrelationAttributesFromNode(node).isEmpty();
} else if (this.file == null || this.file.getSize() <= 0 || StringUtils.isBlank(file.getMd5Hash())) { } else {
return false; return this.file != null
&& this.file.getSize() > 0
&& ((this.file.getMd5Hash() != null) && (!this.file.getMd5Hash().isEmpty()));
} }
boolean isSupported = false;
try {
isSupported = isDownloadParentSupported(node);
} catch (TskCoreException ex) {
LOGGER.log(Level.WARNING, ex.getMessage(), ex);
}
return isSupported;
} }
@Override @Override

View File

@ -336,7 +336,7 @@ public final class CentralRepoAccount {
normalizedAccountIdentifier = accountIdentifier.toLowerCase(); normalizedAccountIdentifier = accountIdentifier.toLowerCase();
} }
} catch (CorrelationAttributeNormalizationException ex) { } catch (CorrelationAttributeNormalizationException ex) {
throw new InvalidAccountIDException("Invalid account identifier", ex); throw new InvalidAccountIDException(String.format("Account id normaization failed, invalid account identifier %s", accountIdentifier), ex);
} }
return normalizedAccountIdentifier; return normalizedAccountIdentifier;

View File

@ -28,3 +28,9 @@ SummaryViewer.contactsLabel.text=Book Entries:
SummaryViewer.accountCountry.text=<account country> SummaryViewer.accountCountry.text=<account country>
SummaryViewer.fileRefPane.border.title=File References in Current Case SummaryViewer.fileRefPane.border.title=File References in Current Case
SummaryViewer.selectAccountFileRefLabel.text=<Select a single account to see File References> SummaryViewer.selectAccountFileRefLabel.text=<Select a single account to see File References>
SummaryViewer.personaPanel.border.title=Personas
PersonaPanel.personaIDLabel.text=jLabel1
SummaryPersonaPane.noPersonaLabel.text=No personas found
SummaryPersonaPane.messageLabel.text=<Enable Central Repository to create and view personas>
SummaryPersonaPane.createButton.text=Create
PersonaPanel.viewButton.text=View

View File

@ -35,6 +35,8 @@ MessageViewer_viewMessage_all=All
MessageViewer_viewMessage_calllogs=Call Logs MessageViewer_viewMessage_calllogs=Call Logs
MessageViewer_viewMessage_selected=Selected MessageViewer_viewMessage_selected=Selected
MessageViewer_viewMessage_unthreaded=Unthreaded MessageViewer_viewMessage_unthreaded=Unthreaded
# {0} - accountIdentifer
SummaryPersonaPane_not_account_in_cr=Unable to find an account with identifier {0} in the Central Repository.
SummaryViewer.countsPanel.border.title=Communications SummaryViewer.countsPanel.border.title=Communications
OutlineViewPanel.messageLabel.text=<Control Disabled> OutlineViewPanel.messageLabel.text=<Control Disabled>
SummaryViewer.messagesDataLabel.text=messages SummaryViewer.messagesDataLabel.text=messages
@ -52,6 +54,8 @@ SummaryViewer_Device_Account_Description=This account was referenced by a device
SummaryViewer_Fetching_References=<Fetching File References> SummaryViewer_Fetching_References=<Fetching File References>
SummaryViewer_FileRef_Message=<Select a single account to see File References> SummaryViewer_FileRef_Message=<Select a single account to see File References>
SummaryViewer_FileRefNameColumn_Title=Path SummaryViewer_FileRefNameColumn_Title=Path
SummaryViewer_Persona_Message=<Enable Central Repository to view Personas>
SummaryViewer_Select_account_for_persona=<Select a single account to see Persona(s)>
SummaryViewer_TabTitle=Summary SummaryViewer_TabTitle=Summary
ThreadRootMessagePanel.showAllCheckBox.text=Show All Messages ThreadRootMessagePanel.showAllCheckBox.text=Show All Messages
ThreadPane.backButton.text=<--- ThreadPane.backButton.text=<---
@ -75,3 +79,9 @@ SummaryViewer.contactsLabel.text=Book Entries:
SummaryViewer.accountCountry.text=<account country> SummaryViewer.accountCountry.text=<account country>
SummaryViewer.fileRefPane.border.title=File References in Current Case SummaryViewer.fileRefPane.border.title=File References in Current Case
SummaryViewer.selectAccountFileRefLabel.text=<Select a single account to see File References> SummaryViewer.selectAccountFileRefLabel.text=<Select a single account to see File References>
SummaryViewer.personaPanel.border.title=Personas
PersonaPanel.personaIDLabel.text=jLabel1
SummaryPersonaPane.noPersonaLabel.text=No personas found
SummaryPersonaPane.messageLabel.text=<Enable Central Repository to create and view personas>
SummaryPersonaPane.createButton.text=Create
PersonaPanel.viewButton.text=View

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<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"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,59,0,0,0,-8"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JLabel" name="personaIDLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="PersonaPanel.personaIDLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JButton" name="viewButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="PersonaPanel.viewButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[0, 5, 0, 5]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="17" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,115 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2020 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 obt ain 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.communications.relationships;
import java.awt.Dimension;
import javax.swing.JButton;
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
/**
*
* Panel to show a single persona with a button for viewing persona details.
*/
public class PersonaPanel extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
private final Persona persona;
/**
* Creates new form PersonaPanel
*/
PersonaPanel(Persona persona) {
initComponents();
this.persona = persona;
personaIDLabel.setText(persona.getName());
}
/**
* Returns the persona displayed by this panel.
*
* @return
*/
Persona getPersona() {
return persona;
}
/**
* Returns the preferred width for the given persona label.
*
* @return
*/
int getPersonaLabelPreferedWidth() {
return personaIDLabel.getPreferredSize().width;
}
/**
* Sets the preferred width for the persona name label.
*
* @param width
*/
void setPersonalLabelPreferredWidth(int width) {
Dimension currentDim = personaIDLabel.getPreferredSize();
personaIDLabel.setPreferredSize(new Dimension(Math.max(currentDim.width, width), currentDim.height));
}
/**
* Returns the View button for this panel.
*
* @return
*/
JButton getViewButton() {
return viewButton;
}
/**
* 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() {
java.awt.GridBagConstraints gridBagConstraints;
personaIDLabel = new javax.swing.JLabel();
viewButton = new javax.swing.JButton();
setLayout(new java.awt.GridBagLayout());
org.openide.awt.Mnemonics.setLocalizedText(personaIDLabel, org.openide.util.NbBundle.getMessage(PersonaPanel.class, "PersonaPanel.personaIDLabel.text")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
add(personaIDLabel, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(viewButton, org.openide.util.NbBundle.getMessage(PersonaPanel.class, "PersonaPanel.viewButton.text")); // NOI18N
viewButton.setMargin(new java.awt.Insets(0, 5, 0, 5));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 0);
add(viewButton, gridBagConstraints);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel personaIDLabel;
private javax.swing.JButton viewButton;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,146 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2020 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 obt ain 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.communications.relationships;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import javax.swing.SwingWorker;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.Account;
import org.sleuthkit.datamodel.AccountFileInstance;
import org.sleuthkit.datamodel.InvalidAccountIDException;
/**
* Runnable SwingWorker for gather the data that the Summary panel needs.
*/
class SummaryPanelWorker extends SwingWorker<SummaryPanelWorker.SummaryWorkerResults, Void> {
private final static Logger logger = Logger.getLogger(SummaryPanelWorker.class.getName());
private final Account account;
// Construct a instance
SummaryPanelWorker(Account account) {
this.account = account;
}
/**
* Returns the account the worker is gathering data for.
*
* @return
*/
Account getAccount() {
return account;
}
@Override
protected SummaryWorkerResults doInBackground() throws Exception {
CentralRepoAccount crAccount = null;
List<String> stringList = new ArrayList<>();
List<AccountFileInstance> accountFileInstanceList = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getAccountFileInstances(account);
for (AccountFileInstance instance : accountFileInstanceList) {
stringList.add(instance.getFile().getUniquePath());
}
List<Persona> personaList = new ArrayList<>();
if (CentralRepository.isEnabled()) {
Collection<PersonaAccount> personaAccountList = PersonaAccount.getPersonaAccountsForAccount(account);
PersonaAccount.getPersonaAccountsForAccount(account);
for (PersonaAccount pAccount : personaAccountList) {
personaList.add(pAccount.getPersona());
}
try {
crAccount = CentralRepository.getInstance().getAccount(CentralRepository.getInstance().getAccountTypeByName(account.getAccountType().getTypeName()), account.getTypeSpecificID());
} catch (InvalidAccountIDException unused) {
// This was probably caused to a phone number not making
// threw the normalization.
logger.log(Level.WARNING, String.format("Exception thrown from CR getAccount for account %s (%d)", account.getTypeSpecificID(), account.getAccountID()));
}
}
return new SummaryWorkerResults(stringList, personaList, crAccount);
}
/**
* Wraps the results of the worker for easy of returning and usage by the
* SummaryViewer.
*/
final static class SummaryWorkerResults {
private final List<String> accountFileInstancePaths;
private final List<Persona> personaList;
private final CentralRepoAccount centralRepoAccount;
/**
* Constructor.
*
* @param accountFileInstancePaths List of instance paths.
* @param personaList List of personas for the account
* @param centralRepoAccount CentralRepoAccount for the given
* account, maybe null if CR is not
* enabled.
*/
SummaryWorkerResults(List<String> accountFileInstancePaths, List<Persona> personaList, CentralRepoAccount centralRepoAccount) {
this.accountFileInstancePaths = accountFileInstancePaths;
this.personaList = personaList;
this.centralRepoAccount = centralRepoAccount;
}
/**
* Returns the list of instance paths for the account given to the
* worker.
*
* @return
*/
List<String> getPaths() {
return accountFileInstancePaths;
}
/**
* Returns the list of personas found for the account given to the
* worker. This list maybe empty if none were found or cr is not
* enabled.
*
* @return
*/
List<Persona> getPersonaList() {
return personaList;
}
/**
* Return the cr account for the account given to the worker. This maybe
* null if the cr was not enabled.
*
* @return
*/
CentralRepoAccount getCRAccount() {
return centralRepoAccount;
}
}
}

View File

@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<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"/>
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,16,0,0,2,121"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignCardLayout"/>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="personaScrollPane">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
<CardConstraints cardName="persona"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
</Container>
<Container class="javax.swing.JPanel" name="messagePane">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
<CardConstraints cardName="message"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JLabel" name="messageLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="SummaryPersonaPane.messageLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="enabled" type="boolean" value="false"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="1.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="createPersonaPanel">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[200, 100]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignCardLayout" value="org.netbeans.modules.form.compat2.layouts.DesignCardLayout$CardConstraintsDescription">
<CardConstraints cardName="create"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JLabel" name="noPersonaLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="SummaryPersonaPane.noPersonaLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="7" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="1.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JButton" name="createButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="SummaryPersonaPane.createButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[0, 5, 0, 5]"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="createButtonActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="2" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,295 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2020 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 obt ain 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.communications.relationships;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JPanel;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount;
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog;
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallback;
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.Account;
/**
* Panel to show the Personas for a given account. That is apart SummaryViewer.
*/
public final class SummaryPersonaPane extends javax.swing.JPanel {
private static final long serialVersionUID = 1L;
private final static Logger logger = Logger.getLogger(SummaryPersonaPane.class.getName());
private final Map<Component, Persona> personaMap;
private final ViewButtonHandler viewButtonHandler = new ViewButtonHandler();
private CentralRepoAccount currentCRAccount = null;
private Account currentAccount = null;
/**
* Creates new form SummaryPersonaPane
*/
SummaryPersonaPane() {
initComponents();
personaScrollPane.setViewportView(new JPanel());
personaMap = new HashMap<>();
}
/**
* Clear the persona list.
*/
void clearList() {
personaScrollPane.setViewportView(new JPanel());
personaMap.clear();
}
/**
* Show the message panel.
*/
void showMessagePanel() {
CardLayout layout = (CardLayout) getLayout();
layout.show(this, "message");
}
/**
* Set the message that appears when the message panel is visible.
*
* @param message Message to show.
*/
void setMessage(String message) {
messageLabel.setText(message);
}
/**
* Update the list of personas to the new given list.
*
* @param personaList New list of personas to show
*/
void updatePersonaList(Account account, CentralRepoAccount crAccount, List<Persona> personaList) {
JPanel panel = new JPanel();
currentCRAccount = crAccount;
currentAccount = account;
CardLayout layout = (CardLayout) getLayout();
if (personaList.isEmpty()) {
layout.show(this, "create");
} else {
panel.setLayout(new GridLayout(personaList.size() + 1, 1));
int maxWidth = 0;
List<PersonaPanel> panelList = new ArrayList<>();
for (Persona persona : personaList) {
PersonaPanel personaPanel = new PersonaPanel(persona);
JButton viewButton = personaPanel.getViewButton();
panel.add(personaPanel);
personaMap.put(viewButton, persona);
viewButton.addActionListener(viewButtonHandler);
panelList.add(personaPanel);
maxWidth = Math.max(personaPanel.getPersonaLabelPreferedWidth(), maxWidth);
}
//Set the preferred width of the labeles to the buttons line up.
if (panelList.size() > 1) {
for (PersonaPanel ppanel : panelList) {
ppanel.setPersonalLabelPreferredWidth(maxWidth);
}
}
panel.add(Box.createVerticalGlue());
personaScrollPane.setViewportView(panel);
layout.show(this, "persona");
}
}
/**
* ActionListener to handle the launching of the view dialog for the given
* persona.
*/
final private class ViewButtonHandler implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
Persona persona = personaMap.get((Component) e.getSource());
new PersonaDetailsDialog(SummaryPersonaPane.this,
PersonaDetailsMode.VIEW, persona, new PersonaViewCallbackImpl());
}
}
/**
* Callback method for the view mode of the PersonaDetailsDialog
*/
private final class PersonaViewCallbackImpl implements PersonaDetailsDialogCallback {
@Override
public void callback(Persona persona) {
// nothing to do
}
}
/**
* Callback class to handle the creation of a new person for the given
* account
*/
private final class PersonaCreateCallbackImpl implements PersonaDetailsDialogCallback {
@Override
public void callback(Persona persona) {
if (persona != null) {
List<Persona> list = new ArrayList<>();
list.add(persona);
CentralRepoAccount crAccount = null;
Collection<PersonaAccount> personaAccounts = null;
try {
personaAccounts = persona.getPersonaAccounts();
} catch (CentralRepoException ex) {
logger.log(Level.WARNING, String.format("Failed to get cr account from person %s (%d)", persona.getName(), persona.getId()), ex);
}
if (personaAccounts != null) {
Iterator<PersonaAccount> iterator = personaAccounts.iterator();
if (iterator.hasNext()) {
crAccount = iterator.next().getAccount();
}
}
updatePersonaList(currentAccount, crAccount, list);
}
}
}
/**
* 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() {
java.awt.GridBagConstraints gridBagConstraints;
personaScrollPane = new javax.swing.JScrollPane();
messagePane = new javax.swing.JPanel();
messageLabel = new javax.swing.JLabel();
createPersonaPanel = new javax.swing.JPanel();
noPersonaLabel = new javax.swing.JLabel();
createButton = new javax.swing.JButton();
setLayout(new java.awt.CardLayout());
personaScrollPane.setBorder(null);
add(personaScrollPane, "persona");
messagePane.setLayout(new java.awt.GridBagLayout());
org.openide.awt.Mnemonics.setLocalizedText(messageLabel, org.openide.util.NbBundle.getMessage(SummaryPersonaPane.class, "SummaryPersonaPane.messageLabel.text")); // NOI18N
messageLabel.setEnabled(false);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.weighty = 1.0;
messagePane.add(messageLabel, gridBagConstraints);
add(messagePane, "message");
createPersonaPanel.setPreferredSize(new java.awt.Dimension(200, 100));
createPersonaPanel.setLayout(new java.awt.GridBagLayout());
org.openide.awt.Mnemonics.setLocalizedText(noPersonaLabel, org.openide.util.NbBundle.getMessage(SummaryPersonaPane.class, "SummaryPersonaPane.noPersonaLabel.text")); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.weighty = 1.0;
gridBagConstraints.insets = new java.awt.Insets(7, 5, 0, 0);
createPersonaPanel.add(noPersonaLabel, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(createButton, org.openide.util.NbBundle.getMessage(SummaryPersonaPane.class, "SummaryPersonaPane.createButton.text")); // NOI18N
createButton.setMargin(new java.awt.Insets(0, 5, 0, 5));
createButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
createButtonActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 0;
gridBagConstraints.gridheight = 2;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
gridBagConstraints.insets = new java.awt.Insets(5, 5, 0, 0);
createPersonaPanel.add(createButton, gridBagConstraints);
add(createPersonaPanel, "create");
}// </editor-fold>//GEN-END:initComponents
@NbBundle.Messages({
"# {0} - accountIdentifer",
"SummaryPersonaPane_not_account_in_cr=Unable to find an account with identifier {0} in the Central Repository."
})
private void createButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createButtonActionPerformed
PersonaDetailsDialog createPersonaDialog = new PersonaDetailsDialog(SummaryPersonaPane.this,
PersonaDetailsMode.CREATE, null, new PersonaCreateCallbackImpl(), false);
// Pre populate the persona name and accounts if we have them.
PersonaDetailsPanel personaPanel = createPersonaDialog.getDetailsPanel();
if (currentCRAccount != null) {
personaPanel.addAccount(currentCRAccount, "", Persona.Confidence.HIGH);
} else {
createPersonaDialog.setStartupPopupMessage(Bundle.SummaryPersonaPane_not_account_in_cr(currentAccount.getTypeSpecificID()));
}
personaPanel.setPersonaName(currentAccount.getTypeSpecificID());
// display the dialog now
createPersonaDialog.display();
}//GEN-LAST:event_createButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton createButton;
private javax.swing.JPanel createPersonaPanel;
private javax.swing.JLabel messageLabel;
private javax.swing.JPanel messagePane;
private javax.swing.JLabel noPersonaLabel;
private javax.swing.JScrollPane personaScrollPane;
// End of variables declaration//GEN-END:variables
}

View File

@ -265,7 +265,7 @@
</Properties> </Properties>
<Constraints> <Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="4" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="9" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="1.0"/> <GridBagConstraints gridX="0" gridY="5" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="9" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="1.0"/>
</Constraint> </Constraint>
</Constraints> </Constraints>
</Component> </Component>
@ -281,7 +281,7 @@
</Properties> </Properties>
<Constraints> <Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription"> <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="1.0"/> <GridBagConstraints gridX="0" gridY="4" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="1.0"/>
</Constraint> </Constraint>
</Constraints> </Constraints>
@ -363,5 +363,32 @@
</Container> </Container>
</SubComponents> </SubComponents>
</Container> </Container>
<Container class="javax.swing.JPanel" name="personaPanel">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Personas">
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/communications/relationships/Bundle.properties" key="SummaryViewer.personaPanel.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</TitledBorder>
</Border>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[35, 75]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[112, 75]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new SummaryPersonaPane()"/>
</AuxValues>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="-1" gridY="3" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
</Container>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -1,7 +1,7 @@
/* /*
* Autopsy Forensic Browser * Autopsy Forensic Browser
* *
* Copyright 2019 Basis Technology Corp. * Copyright 2019-2020 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org * Contact: carrier <at> sleuthkit <dot> org
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
@ -19,13 +19,11 @@
package org.sleuthkit.autopsy.communications.relationships; package org.sleuthkit.autopsy.communications.relationships;
import java.awt.CardLayout; import java.awt.CardLayout;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.DefaultListModel; import javax.swing.DefaultListModel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.SwingWorker;
import org.netbeans.swing.outline.DefaultOutlineModel; import org.netbeans.swing.outline.DefaultOutlineModel;
import org.netbeans.swing.outline.Outline; import org.netbeans.swing.outline.Outline;
import org.openide.explorer.view.OutlineView; import org.openide.explorer.view.OutlineView;
@ -33,11 +31,10 @@ import org.openide.nodes.AbstractNode;
import org.openide.nodes.Children; import org.openide.nodes.Children;
import org.openide.util.Lookup; import org.openide.util.Lookup;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.Account; import org.sleuthkit.datamodel.Account;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AccountFileInstance;
/** /**
* Account Summary View Panel. This panel shows a list of various counts related * Account Summary View Panel. This panel shows a list of various counts related
@ -47,6 +44,8 @@ import org.sleuthkit.datamodel.AccountFileInstance;
*/ */
public class SummaryViewer extends javax.swing.JPanel implements RelationshipsViewer { public class SummaryViewer extends javax.swing.JPanel implements RelationshipsViewer {
private static final long serialVersionUID = 1L;
private final Lookup lookup; private final Lookup lookup;
private final DefaultListModel<String> fileRefListModel; private final DefaultListModel<String> fileRefListModel;
@ -62,7 +61,8 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
"SummaryViewer_Device_Account_Description=This account was referenced by a device in the case.", "SummaryViewer_Device_Account_Description=This account was referenced by a device in the case.",
"SummaryViewer_Account_Description=This account represents a device in the case.", "SummaryViewer_Account_Description=This account represents a device in the case.",
"SummaryViewer_Account_Description_MuliSelect=Summary information is not available when multiple accounts are selected.", "SummaryViewer_Account_Description_MuliSelect=Summary information is not available when multiple accounts are selected.",
"SummaryViewer_Country_Code=Country: " "SummaryViewer_Country_Code=Country: ",
"SummaryViewer_Select_account_for_persona=<Select a single account to see Persona(s)>"
}) })
/** /**
@ -85,6 +85,8 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
clearControls(); clearControls();
caseReferencesPanel.hideOutlineView(Bundle.SummaryViewer_CentralRepository_Message()); caseReferencesPanel.hideOutlineView(Bundle.SummaryViewer_CentralRepository_Message());
((SummaryPersonaPane)personaPanel).setMessage(Bundle.SummaryViewer_Select_account_for_persona());
((SummaryPersonaPane)personaPanel).showMessagePanel();
} }
@Override @Override
@ -153,7 +155,7 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
caseReferencesPanel.setNode(new AbstractNode(Children.create(new CorrelationCaseChildNodeFactory(info.getAccounts()), true))); caseReferencesPanel.setNode(new AbstractNode(Children.create(new CorrelationCaseChildNodeFactory(info.getAccounts()), true)));
updateFileReferences(account); updateOtherAccountInfo(account);
setEnabled(true); setEnabled(true);
} }
@ -202,24 +204,17 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
} }
@Messages({ @Messages({
"SummaryViewer_Fetching_References=<Fetching File References>" "SummaryViewer_Fetching_References=<Fetching File References>",
"SummaryViewer_Persona_Message=<Enable Central Repository to view Personas>"
}) })
private void updateFileReferences(final Account account) { private void updateOtherAccountInfo(final Account account) {
SwingWorker<List<String>, Void> worker = new SwingWorker<List<String>, Void>() { SummaryPanelWorker worker = new SummaryPanelWorker(account) {
@Override
protected List<String> doInBackground() throws Exception {
List<String> stringList = new ArrayList<>();
List<AccountFileInstance> accountFileInstanceList = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager().getAccountFileInstances(account);
for (AccountFileInstance instance : accountFileInstanceList) {
stringList.add(instance.getFile().getUniquePath());
}
return stringList;
}
@Override @Override
protected void done() { protected void done() {
try { try {
List<String> fileRefList = get(); SummaryPanelWorker.SummaryWorkerResults results = get();
List<String> fileRefList = results.getPaths();
fileRefList.forEach(value -> { fileRefList.forEach(value -> {
fileRefListModel.addElement(value); fileRefListModel.addElement(value);
@ -227,10 +222,20 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
CardLayout cardLayout = (CardLayout) fileRefPane.getLayout(); CardLayout cardLayout = (CardLayout) fileRefPane.getLayout();
cardLayout.show(fileRefPane, "listPanelCard"); cardLayout.show(fileRefPane, "listPanelCard");
List<Persona> personaList = results.getPersonaList();
if (CentralRepository.isEnabled()) {
((SummaryPersonaPane) personaPanel).updatePersonaList(account, results.getCRAccount(), personaList);
} else {
((SummaryPersonaPane) personaPanel).setMessage("Bundle.SummaryViewer_Persona_Message()");
((SummaryPersonaPane) personaPanel).showMessagePanel();
}
} catch (InterruptedException | ExecutionException ex) { } catch (InterruptedException | ExecutionException ex) {
logger.log(Level.WARNING, String.format(("Failed to get file references for account: %d"), account.getAccountID()), ex); logger.log(Level.WARNING, String.format(("Failed to get data for account: %d"), account.getAccountID()), ex);
} }
} }
}; };
@ -273,6 +278,7 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
fileRefList = new javax.swing.JList<>(); fileRefList = new javax.swing.JList<>();
javax.swing.JPanel selectAccountPane = new javax.swing.JPanel(); javax.swing.JPanel selectAccountPane = new javax.swing.JPanel();
selectAccountFileRefLabel = new javax.swing.JLabel(); selectAccountFileRefLabel = new javax.swing.JLabel();
personaPanel = new SummaryPersonaPane();
setLayout(new java.awt.GridBagLayout()); setLayout(new java.awt.GridBagLayout());
@ -430,7 +436,7 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
caseReferencesPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(SummaryViewer.class, "SummaryViewer.caseReferencesPanel.border.title"))); // NOI18N caseReferencesPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(SummaryViewer.class, "SummaryViewer.caseReferencesPanel.border.title"))); // NOI18N
gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0; gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 4; gridBagConstraints.gridy = 5;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.weightx = 1.0; gridBagConstraints.weightx = 1.0;
@ -464,11 +470,19 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
gridBagConstraints = new java.awt.GridBagConstraints(); gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0; gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 3; gridBagConstraints.gridy = 4;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST; gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.weighty = 1.0; gridBagConstraints.weighty = 1.0;
add(fileRefPane, gridBagConstraints); add(fileRefPane, gridBagConstraints);
personaPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(SummaryViewer.class, "SummaryViewer.personaPanel.border.title"))); // NOI18N
personaPanel.setMinimumSize(new java.awt.Dimension(35, 75));
personaPanel.setPreferredSize(new java.awt.Dimension(112, 75));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridy = 3;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
add(personaPanel, gridBagConstraints);
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@ -489,6 +503,7 @@ public class SummaryViewer extends javax.swing.JPanel implements RelationshipsVi
private javax.swing.JPanel fileRefPane; private javax.swing.JPanel fileRefPane;
private javax.swing.JLabel messagesDataLabel; private javax.swing.JLabel messagesDataLabel;
private javax.swing.JLabel messagesLabel; private javax.swing.JLabel messagesLabel;
private javax.swing.JPanel personaPanel;
private javax.swing.JLabel referencesDataLabel; private javax.swing.JLabel referencesDataLabel;
private javax.swing.JLabel referencesLabel; private javax.swing.JLabel referencesLabel;
private javax.swing.JLabel selectAccountFileRefLabel; private javax.swing.JLabel selectAccountFileRefLabel;

View File

@ -28,11 +28,8 @@ import org.openide.util.NbBundle;
import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector; import org.sleuthkit.autopsy.modules.filetypeid.FileTypeDetector;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.TskCoreException;
/** /**
* Generic Application content viewer * Generic Application content viewer
@ -40,11 +37,11 @@ import org.sleuthkit.datamodel.TskCoreException;
@ServiceProvider(service = DataContentViewer.class, position = 3) @ServiceProvider(service = DataContentViewer.class, position = 3)
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
public class FileViewer extends javax.swing.JPanel implements DataContentViewer { public class FileViewer extends javax.swing.JPanel implements DataContentViewer {
private static final int CONFIDENCE_LEVEL = 5; private static final int CONFIDENCE_LEVEL = 5;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(FileViewer.class.getName()); private static final Logger LOGGER = Logger.getLogger(FileViewer.class.getName());
private final Map<String, FileTypeViewer> mimeTypeToViewerMap = new HashMap<>(); private final Map<String, FileTypeViewer> mimeTypeToViewerMap = new HashMap<>();
// TBD: This hardcoded list of viewers should be replaced with a dynamic lookup // TBD: This hardcoded list of viewers should be replaced with a dynamic lookup
@ -56,7 +53,7 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
new WindowsRegistryViewer(), new WindowsRegistryViewer(),
new PDFViewer() new PDFViewer()
}; };
private FileTypeViewer lastViewer; private FileTypeViewer lastViewer;
/** /**
@ -74,9 +71,9 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
} }
}); });
} }
initComponents(); initComponents();
LOGGER.log(Level.INFO, "Created ApplicationContentViewer instance: {0}", this); //NON-NLS LOGGER.log(Level.INFO, "Created ApplicationContentViewer instance: {0}", this); //NON-NLS
} }
@ -85,7 +82,8 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
* *
* @param file * @param file
* *
* @return FileTypeViewer, null if no known content viewer supports the file * @return FileTypeViewer, null if no known content viewer supports the
* file
*/ */
private FileTypeViewer getSupportingViewer(AbstractFile file) { private FileTypeViewer getSupportingViewer(AbstractFile file) {
FileTypeViewer viewer = mimeTypeToViewerMap.get(file.getMIMEType()); FileTypeViewer viewer = mimeTypeToViewerMap.get(file.getMIMEType());
@ -112,18 +110,18 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
// End of variables declaration//GEN-END:variables // End of variables declaration//GEN-END:variables
@Override @Override
public void setNode(Node selectedNode) { public void setNode(Node selectedNode) {
resetComponent(); resetComponent();
if (selectedNode == null || !isSupported(selectedNode)) { if (selectedNode == null) {
return; return;
} }
AbstractFile file = selectedNode.getLookup().lookup(AbstractFile.class); AbstractFile file = selectedNode.getLookup().lookup(AbstractFile.class);
if ((file == null) || (file.isDir())) { if ((file == null) || (file.isDir())) {
return; return;
} }
String mimeType = file.getMIMEType(); String mimeType = file.getMIMEType();
if (Strings.isNullOrEmpty(mimeType)) { if (Strings.isNullOrEmpty(mimeType)) {
LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", file.getName()); //NON-NLS LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", file.getName()); //NON-NLS
@ -135,81 +133,67 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
return; return;
} }
} }
if (mimeType.equalsIgnoreCase("application/octet-stream")) { if (mimeType.equalsIgnoreCase("application/octet-stream")) {
return; return;
} else { } else {
FileTypeViewer viewer = getSupportingViewer(file); FileTypeViewer viewer = getSupportingViewer(file);
if (viewer != null) { if (viewer != null) {
lastViewer = viewer; lastViewer = viewer;
viewer.setFile(file); viewer.setFile(file);
this.removeAll(); this.removeAll();
this.add(viewer.getComponent()); this.add(viewer.getComponent());
this.validate(); this.validate();
} }
} }
} }
@Override @Override
@NbBundle.Messages("ApplicationContentViewer.title=Application") @NbBundle.Messages("ApplicationContentViewer.title=Application")
public String getTitle() { public String getTitle() {
return Bundle.ApplicationContentViewer_title(); return Bundle.ApplicationContentViewer_title();
} }
@Override @Override
@NbBundle.Messages("ApplicationContentViewer.toolTip=Displays file contents.") @NbBundle.Messages("ApplicationContentViewer.toolTip=Displays file contents.")
public String getToolTip() { public String getToolTip() {
return Bundle.ApplicationContentViewer_toolTip(); return Bundle.ApplicationContentViewer_toolTip();
} }
@Override @Override
public DataContentViewer createInstance() { public DataContentViewer createInstance() {
return new FileViewer(); return new FileViewer();
} }
@Override @Override
public Component getComponent() { public Component getComponent() {
return this; return this;
} }
@Override @Override
public void resetComponent() { public void resetComponent() {
if (lastViewer != null) { if (lastViewer != null) {
lastViewer.resetComponent(); lastViewer.resetComponent();
} }
this.removeAll(); this.removeAll();
lastViewer = null; lastViewer = null;
} }
@Override @Override
public boolean isSupported(Node node) { public boolean isSupported(Node node) {
if (node == null) { if (node == null) {
return false; return false;
} }
AbstractFile aFile = node.getLookup().lookup(AbstractFile.class); AbstractFile aFile = node.getLookup().lookup(AbstractFile.class);
if ((aFile == null) || (aFile.isDir())) { if ((aFile == null) || (aFile.isDir())) {
return false; return false;
} }
if (node instanceof BlackboardArtifactNode) {
BlackboardArtifact theArtifact = ((BlackboardArtifactNode) node).getArtifact();
//disable the content viewer when a download or cached file does not exist instead of displaying its parent
try {
if ((theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& aFile.getId() == theArtifact.getParent().getId()) {
return false;
}
} catch (TskCoreException ex) {
LOGGER.log(Level.WARNING, String.format("Error getting parent of artifact with type %s and objID = %d can not confirm file with name %s and objId = %d is not the parent. File content viewer will not be supported.",
theArtifact.getArtifactTypeName(), theArtifact.getObjectID(), aFile.getName(), aFile.getId()), ex);
return false;
}
}
String mimeType = aFile.getMIMEType(); String mimeType = aFile.getMIMEType();
if (Strings.isNullOrEmpty(mimeType)) { if (Strings.isNullOrEmpty(mimeType)) {
LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", aFile.getName()); //NON-NLS LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", aFile.getName()); //NON-NLS
@ -221,20 +205,20 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
return false; return false;
} }
} }
if (mimeType.equalsIgnoreCase("application/octet-stream")) { if (mimeType.equalsIgnoreCase("application/octet-stream")) {
return false; return false;
} else { } else {
return (getSupportingViewer(aFile) != null); return (getSupportingViewer(aFile) != null);
} }
} }
@Override @Override
public int isPreferred(Node node) { public int isPreferred(Node node) {
AbstractFile file = node.getLookup().lookup(AbstractFile.class); AbstractFile file = node.getLookup().lookup(AbstractFile.class);
String mimeType = file.getMIMEType(); String mimeType = file.getMIMEType();
if (Strings.isNullOrEmpty(mimeType)) { if (Strings.isNullOrEmpty(mimeType)) {
LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", file.getName()); //NON-NLS LOGGER.log(Level.INFO, "Mimetype not known for file: {0}", file.getName()); //NON-NLS
try { try {
@ -245,7 +229,7 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
return 0; return 0;
} }
} }
if (mimeType.equalsIgnoreCase("application/octet-stream")) { if (mimeType.equalsIgnoreCase("application/octet-stream")) {
return 0; return 0;
} else { } else {
@ -253,7 +237,7 @@ public class FileViewer extends javax.swing.JPanel implements DataContentViewer
return CONFIDENCE_LEVEL; return CONFIDENCE_LEVEL;
} }
} }
return 0; return 0;
} }
} }

View File

@ -29,7 +29,6 @@ import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
@ -51,7 +50,7 @@ import org.sleuthkit.datamodel.TskData.TSK_DB_FILES_TYPE_ENUM;
public class Metadata extends javax.swing.JPanel implements DataContentViewer { public class Metadata extends javax.swing.JPanel implements DataContentViewer {
private static final Logger LOGGER = Logger.getLogger(Metadata.class.getName()); private static final Logger LOGGER = Logger.getLogger(Metadata.class.getName());
/** /**
* Creates new form Metadata * Creates new form Metadata
*/ */
@ -149,10 +148,6 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
"Metadata.nodeText.none=None"}) "Metadata.nodeText.none=None"})
@Override @Override
public void setNode(Node node) { public void setNode(Node node) {
if ((node == null) || (!isSupported(node))) {
resetComponent();
return;
}
AbstractFile file = node.getLookup().lookup(AbstractFile.class); AbstractFile file = node.getLookup().lookup(AbstractFile.class);
Image image = node.getLookup().lookup(Image.class); Image image = node.getLookup().lookup(Image.class);
DataSource dataSource = node.getLookup().lookup(DataSource.class); DataSource dataSource = node.getLookup().lookup(DataSource.class);
@ -181,6 +176,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.created"), ContentUtils.getStringTime(file.getCrtime(), file)); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.created"), ContentUtils.getStringTime(file.getCrtime(), file));
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.changed"), ContentUtils.getStringTime(file.getCtime(), file)); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.changed"), ContentUtils.getStringTime(file.getCtime(), file));
String md5 = file.getMd5Hash(); String md5 = file.getMd5Hash();
if (md5 == null) { if (md5 == null) {
md5 = NbBundle.getMessage(this.getClass(), "Metadata.tableRowContent.md5notCalc"); md5 = NbBundle.getMessage(this.getClass(), "Metadata.tableRowContent.md5notCalc");
@ -193,12 +189,12 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.sha256"), sha256); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.sha256"), sha256);
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.hashLookupResults"), file.getKnown().toString()); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.hashLookupResults"), file.getKnown().toString());
addAcquisitionDetails(sb, dataSource); addAcquisitionDetails(sb, dataSource);
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.internalid"), Long.toString(file.getId())); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.internalid"), Long.toString(file.getId()));
if (file.getType().compareTo(TSK_DB_FILES_TYPE_ENUM.LOCAL) == 0) { if (file.getType().compareTo(TSK_DB_FILES_TYPE_ENUM.LOCAL) == 0) {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), file.getLocalAbsPath()); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), file.getLocalAbsPath());
} }
try { try {
List<BlackboardArtifact> associatedObjectArtifacts = file.getArtifacts(ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT); List<BlackboardArtifact> associatedObjectArtifacts = file.getArtifacts(ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT);
if (!associatedObjectArtifacts.isEmpty()) { if (!associatedObjectArtifacts.isEmpty()) {
@ -211,14 +207,14 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
} }
} }
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.exceptionNotice.text")).append(ex.getLocalizedMessage()); sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.exceptionNotice.text")).append(ex.getLocalizedMessage());
} }
endTable(sb); endTable(sb);
/* /*
* If we have a file system file, grab the more detailed metadata * If we have a file system file, grab the more detailed metadata text
* text too * too
*/ */
try { try {
if (file instanceof FsContent) { if (file instanceof FsContent) {
@ -230,11 +226,11 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
for (String str : fsFile.getMetaDataText()) { for (String str : fsFile.getMetaDataText()) {
sb.append(str).append("<br />"); //NON-NLS sb.append(str).append("<br />"); //NON-NLS
/* /*
* Very long results can cause the UI to hang before * Very long results can cause the UI to hang before displaying,
* displaying, so truncate the results if necessary. * so truncate the results if necessary.
*/ */
if (sb.length() > 50000) { if(sb.length() > 50000){
sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.truncated")); sb.append(NbBundle.getMessage(this.getClass(), "Metadata.nodeText.truncated"));
break; break;
} }
@ -250,7 +246,7 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
} catch (TskCoreException ex) { } catch (TskCoreException ex) {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.name"), image.getName()); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.name"), image.getName());
} }
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.imageType"), image.getType().getName()); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.imageType"), image.getType().getName());
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.size"), Long.toString(image.getSize())); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.size"), Long.toString(image.getSize()));
try { try {
@ -286,46 +282,46 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
StringBuilder pathValues = new StringBuilder("<div>"); StringBuilder pathValues = new StringBuilder("<div>");
pathValues.append(imagePaths[0]); pathValues.append(imagePaths[0]);
pathValues.append("</div>"); pathValues.append("</div>");
for (int i = 1; i < imagePaths.length; i++) { for (int i=1; i < imagePaths.length; i++) {
pathValues.append("<div>"); pathValues.append("<div>");
pathValues.append(imagePaths[i]); pathValues.append(imagePaths[i]);
pathValues.append("</div>"); pathValues.append("</div>");
} }
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), pathValues.toString()); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), pathValues.toString());
} else { } else {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"), addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.localPath"),
NbBundle.getMessage(this.getClass(), "Metadata.nodeText.none")); NbBundle.getMessage(this.getClass(), "Metadata.nodeText.none"));
} }
} }
setText(sb.toString()); setText(sb.toString());
jTextPane1.setCaretPosition(0); jTextPane1.setCaretPosition(0);
this.setCursor(null); this.setCursor(null);
} }
/** /**
* Adds a row for download source from the given associated artifact, if the * Adds a row for download source from the given associated artifact,
* associated artifacts specifies a source. * if the associated artifacts specifies a source.
* *
* @param sb string builder. * @param sb string builder.
* @param associatedArtifact * @param associatedArtifact
* *
* @throws TskCoreException if there is an error * @throws TskCoreException if there is an error
*/ */
private void addDownloadSourceRow(StringBuilder sb, BlackboardArtifact associatedArtifact) throws TskCoreException { private void addDownloadSourceRow(StringBuilder sb, BlackboardArtifact associatedArtifact ) throws TskCoreException {
if (associatedArtifact != null if (associatedArtifact != null &&
&& ((associatedArtifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) ((associatedArtifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()) ||
|| (associatedArtifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID()))) { (associatedArtifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())) ) {
BlackboardAttribute urlAttr = associatedArtifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_URL)); BlackboardAttribute urlAttr = associatedArtifact.getAttribute(new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_URL));
if (urlAttr != null) { if (urlAttr != null) {
addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.downloadSource"), urlAttr.getValueString()); addRow(sb, NbBundle.getMessage(this.getClass(), "Metadata.tableRowTitle.downloadSource"), urlAttr.getValueString());
} }
} }
} }
/** /**
* Add the acquisition details to the results (if applicable) * Add the acquisition details to the results (if applicable)
* *
* @param sb The output StringBuilder object * @param sb The output StringBuilder object
* @param dataSource The data source (may be null) * @param dataSource The data source (may be null)
*/ */
@ -373,22 +369,6 @@ public class Metadata extends javax.swing.JPanel implements DataContentViewer {
public boolean isSupported(Node node) { public boolean isSupported(Node node) {
Image image = node.getLookup().lookup(Image.class); Image image = node.getLookup().lookup(Image.class);
AbstractFile file = node.getLookup().lookup(AbstractFile.class); AbstractFile file = node.getLookup().lookup(AbstractFile.class);
if (file != null && node instanceof BlackboardArtifactNode) {
BlackboardArtifact theArtifact = ((BlackboardArtifactNode) node).getArtifact();
//disable the content viewer when a download or cached file does not exist instead of displaying its parent
try {
if ((theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& file.getId() == theArtifact.getParent().getId()) {
return false;
}
} catch (TskCoreException ex) {
LOGGER.log(Level.WARNING, String.format("Error getting parent of artifact with type %s and objID = %d can not confirm file with name %s and objId = %d is not the parent. Metadata viewer will not be supported.",
theArtifact.getArtifactTypeName(), theArtifact.getObjectID(), file.getName(), file.getId()), ex);
return false;
}
}
return (file != null) || (image != null); return (file != null) || (image != null);
} }

View File

@ -36,7 +36,6 @@ import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT; import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
@ -226,21 +225,6 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
// check if the node has an abstract file and the file has any context defining artifacts. // check if the node has an abstract file and the file has any context defining artifacts.
if (node.getLookup().lookup(AbstractFile.class) != null) { if (node.getLookup().lookup(AbstractFile.class) != null) {
AbstractFile abstractFile = node.getLookup().lookup(AbstractFile.class); AbstractFile abstractFile = node.getLookup().lookup(AbstractFile.class);
if (node instanceof BlackboardArtifactNode) {
BlackboardArtifact theArtifact = ((BlackboardArtifactNode) node).getArtifact();
//disable the content viewer when a download or cached file does not exist instead of displaying its parent
try {
if ((theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& abstractFile.getId() == theArtifact.getParent().getId()) {
return false;
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, String.format("Error getting parent of artifact with type %s and objID = %d can not confirm file with name %s and objId = %d is not the parent. Context content viewer will not be supported.",
theArtifact.getArtifactTypeName(), theArtifact.getObjectID(), abstractFile.getName(), abstractFile.getId()), ex);
return false;
}
}
for (BlackboardArtifact.ARTIFACT_TYPE artifactType : CONTEXT_ARTIFACTS) { for (BlackboardArtifact.ARTIFACT_TYPE artifactType : CONTEXT_ARTIFACTS) {
List<BlackboardArtifact> artifactsList; List<BlackboardArtifact> artifactsList;
try { try {
@ -265,7 +249,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
} }
@NbBundle.Messages({ @NbBundle.Messages({
"ContextViewer.unknownSource=Unknown ",}) "ContextViewer.unknownSource=Unknown ",
})
/** /**
* Looks for context providing artifacts for the given file and populates * Looks for context providing artifacts for the given file and populates
* the source context. * the source context.
@ -278,7 +263,7 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
private void populatePanels(AbstractFile sourceFile) throws NoCurrentCaseException, TskCoreException { private void populatePanels(AbstractFile sourceFile) throws NoCurrentCaseException, TskCoreException {
SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase(); SleuthkitCase tskCase = Case.getCurrentCaseThrows().getSleuthkitCase();
// Check for all context artifacts // Check for all context artifacts
boolean foundASource = false; boolean foundASource = false;
for (BlackboardArtifact.ARTIFACT_TYPE artifactType : CONTEXT_ARTIFACTS) { for (BlackboardArtifact.ARTIFACT_TYPE artifactType : CONTEXT_ARTIFACTS) {
@ -307,7 +292,7 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
contextContainer.add(usagePanel); contextContainer.add(usagePanel);
} }
} }
contextContainer.setBackground(javax.swing.UIManager.getDefaults().getColor("window")); contextContainer.setBackground(javax.swing.UIManager.getDefaults().getColor("window"));
contextContainer.setEnabled(foundASource); contextContainer.setEnabled(foundASource);
contextContainer.setVisible(foundASource); contextContainer.setVisible(foundASource);
@ -316,12 +301,12 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
jScrollPane.setVisible(foundASource); jScrollPane.setVisible(foundASource);
jScrollPane.repaint(); jScrollPane.repaint();
jScrollPane.revalidate(); jScrollPane.revalidate();
} }
/** /**
* Resolves an TSK_ASSOCIATED_OBJECT artifact and adds it to the appropriate * Resolves an TSK_ASSOCIATED_OBJECT artifact and adds it to the appropriate panel
* panel
* *
* @param artifact Artifact that may provide context. * @param artifact Artifact that may provide context.
* *
@ -373,16 +358,16 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == associatedArtifact.getArtifactTypeID()) { } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == associatedArtifact.getArtifactTypeID()) {
String sourceName = Bundle.ContextViewer_recentDocs(); String sourceName = Bundle.ContextViewer_recentDocs();
String sourceText = recentDocArtifactToString(associatedArtifact); String sourceText = recentDocArtifactToString(associatedArtifact);
ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime); ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime);
contextUsagePanels.add(usagePanel); contextUsagePanels.add(usagePanel);
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == associatedArtifact.getArtifactTypeID()) { } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == associatedArtifact.getArtifactTypeID()) {
String sourceName = Bundle.ContextViewer_programExecution(); String sourceName = Bundle.ContextViewer_programExecution();
String sourceText = programExecArtifactToString(associatedArtifact); String sourceText = programExecArtifactToString(associatedArtifact);
ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime); ContextUsagePanel usagePanel = new ContextUsagePanel(sourceName, sourceText, associatedArtifact, dateTime);
contextUsagePanels.add(usagePanel); contextUsagePanels.add(usagePanel);
} }
Collections.sort(contextSourcePanels, new SortByDateTime()); Collections.sort(contextSourcePanels, new SortByDateTime());
Collections.sort(contextUsagePanels, new SortByDateTime()); Collections.sort(contextUsagePanels, new SortByDateTime());
} }
@ -414,7 +399,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
} }
/** /**
* Returns a display string with recent Doc artifact. * Returns a display string with recent Doc
* artifact.
* *
* @param artifact artifact to get doc from. * @param artifact artifact to get doc from.
* *
@ -429,9 +415,9 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
private String recentDocArtifactToString(BlackboardArtifact artifact) throws TskCoreException { private String recentDocArtifactToString(BlackboardArtifact artifact) throws TskCoreException {
StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN); StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN);
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact); Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME); BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == artifact.getArtifactTypeID()) { if (BlackboardArtifact.ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID() == artifact.getArtifactTypeID()) {
if (attribute != null && attribute.getValueLong() > 0) { if (attribute != null && attribute.getValueLong() > 0) {
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_on()); appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_on());
@ -443,7 +429,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
} }
/** /**
* Returns a display string with Program Execution artifact. * Returns a display string with Program Execution
* artifact.
* *
* @param artifact artifact to get doc from. * @param artifact artifact to get doc from.
* *
@ -458,9 +445,9 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
private String programExecArtifactToString(BlackboardArtifact artifact) throws TskCoreException { private String programExecArtifactToString(BlackboardArtifact artifact) throws TskCoreException {
StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN); StringBuilder sb = new StringBuilder(ARTIFACT_STR_MAX_LEN);
Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact); Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributesMap = getAttributesMap(artifact);
BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME); BlackboardAttribute attribute = attributesMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME);
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == artifact.getArtifactTypeID()) { if (BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN.getTypeID() == artifact.getArtifactTypeID()) {
if (attribute != null && attribute.getValueLong() > 0) { if (attribute != null && attribute.getValueLong() > 0) {
appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_runOn()); appendAttributeString(sb, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, attributesMap, Bundle.ContextViewer_runOn());
@ -551,9 +538,8 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
return attributeMap; return attributeMap;
} }
interface DateTimePanel { interface DateTimePanel {
/** /**
* Return the date time value for this panel. * Return the date time value for this panel.
* *
@ -561,28 +547,28 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
*/ */
Long getDateTime(); Long getDateTime();
} }
/** /**
* Return the dateTime value for the given message artifact. * Return the dateTime value for the given message artifact.
* *
* @param artifact * @param artifact
* *
* @return Long dateTime value or null if the attribute was not found. * @return Long dateTime value or null if the attribute was not found.
* *
* @throws TskCoreException * @throws TskCoreException
*/ */
private Long getArtifactDateTime(BlackboardArtifact artifact) throws TskCoreException { private Long getArtifactDateTime(BlackboardArtifact artifact) throws TskCoreException {
BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME)); BlackboardAttribute attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME));
if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == artifact.getArtifactTypeID()) { if (BlackboardArtifact.ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() == artifact.getArtifactTypeID()) {
attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT)); attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_SENT));
} else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifact.getArtifactTypeID() } else if (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifact.getArtifactTypeID()
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == artifact.getArtifactTypeID()) { || BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID() == artifact.getArtifactTypeID()) {
attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED)); attribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED));
} }
return (attribute != null ? attribute.getValueLong() : null); return (attribute != null ? attribute.getValueLong() : null);
} }
/** /**
* Class for sorting lists of DateTimePanels. * Class for sorting lists of DateTimePanels.
*/ */
@ -592,18 +578,18 @@ public final class ContextViewer extends javax.swing.JPanel implements DataConte
public int compare(DateTimePanel panel1, DateTimePanel panel2) { public int compare(DateTimePanel panel1, DateTimePanel panel2) {
Long dateTime1 = panel1.getDateTime(); Long dateTime1 = panel1.getDateTime();
Long dateTime2 = panel2.getDateTime(); Long dateTime2 = panel2.getDateTime();
if (dateTime1 == null && dateTime2 == null) { if(dateTime1 == null && dateTime2 == null) {
return 0; return 0;
} else if (dateTime1 == null) { } else if(dateTime1 == null) {
return -1; return -1;
} else if (dateTime2 == null) { } else if(dateTime2 == null) {
return 1; return 1;
} }
return dateTime1.compareTo(dateTime2); return dateTime1.compareTo(dateTime2);
} }
} }

View File

@ -19,16 +19,11 @@
package org.sleuthkit.autopsy.contentviewers.textcontentviewer; package org.sleuthkit.autopsy.contentviewers.textcontentviewer;
import java.awt.Component; import java.awt.Component;
import java.util.logging.Level;
import org.openide.nodes.Node; import org.openide.nodes.Node;
import org.openide.util.NbBundle.Messages; import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.ServiceProvider; import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.TskCoreException;
/** /**
* A DataContentViewer that displays text with the TextViewers available. * A DataContentViewer that displays text with the TextViewers available.
@ -38,7 +33,6 @@ public class TextContentViewer implements DataContentViewer {
private final TextContentViewerPanel panel; private final TextContentViewerPanel panel;
private volatile Node currentNode = null; private volatile Node currentNode = null;
private static final Logger logger = Logger.getLogger(TextContentViewer.class.getName());
/** /**
* No arg constructor for creating the main instance of this Content Viewer. * No arg constructor for creating the main instance of this Content Viewer.
@ -58,10 +52,6 @@ public class TextContentViewer implements DataContentViewer {
@Override @Override
public void setNode(Node selectedNode) { public void setNode(Node selectedNode) {
if ((selectedNode == null) || (!isSupported(selectedNode))) {
resetComponent();
return;
}
currentNode = selectedNode; currentNode = selectedNode;
panel.setNode(currentNode); panel.setNode(currentNode);
@ -106,26 +96,12 @@ public class TextContentViewer implements DataContentViewer {
if (file == null) { if (file == null) {
return false; return false;
} }
if (node instanceof BlackboardArtifactNode) {
BlackboardArtifact theArtifact = ((BlackboardArtifactNode) node).getArtifact();
//disable the content viewer when a download or cached file does not exist instead of displaying its parent
try {
if ((theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& file.getId() == theArtifact.getParent().getId()) {
return false;
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, String.format("Error getting parent of artifact with type %s and objID = %d can not confirm file with name %s and objId = %d is not the parent. Text content viewer will not be supported.",
theArtifact.getArtifactTypeName(), theArtifact.getObjectID(), file.getName(), file.getId()), ex);
return false;
}
}
// disable the text content viewer for directories and empty files // disable the text content viewer for directories and empty files
if (file.isDir() || file.getSize() == 0) { if (file.isDir() || file.getSize() == 0) {
return false; return false;
} }
return panel.isSupported(node); return panel.isSupported(node);
} }

View File

@ -501,39 +501,24 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
Lookup lookup = selectedNode.getLookup(); Lookup lookup = selectedNode.getLookup();
// Get the content. We may get BlackboardArtifacts, ignore those here. // Get the content. We may get BlackboardArtifacts, ignore those here.
ArrayList<BlackboardArtifact> artifacts = new ArrayList<>();
Collection<? extends Content> contents = lookup.lookupAll(Content.class); Collection<? extends Content> contents = lookup.lookupAll(Content.class);
if (contents.isEmpty()) { if (contents.isEmpty()) {
return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT); return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT);
} }
Content underlyingContent = null; Content underlyingContent = null;
//find the first non-artifact content from the lookup results
for (Content content : contents) { for (Content content : contents) {
if ((content != null) && (!(content instanceof BlackboardArtifact))) { if ((content != null) && (!(content instanceof BlackboardArtifact))) {
underlyingContent = content; // Get all of the blackboard artifacts associated with the content. These are what this
break; // viewer displays.
} try {
} artifacts = content.getAllArtifacts();
ArrayList<BlackboardArtifact> contentArtifacts = new ArrayList<>(); underlyingContent = content;
if (underlyingContent != null) { break;
try { } catch (TskException ex) {
//get the artifacts seperately for the use case where an artifact is about a file that exists other than its parent such as a TSK_WEB_DOWNLOAD or TSK_WEB_CACHE logger.log(Level.SEVERE, "Couldn't get artifacts", ex); //NON-NLS
Collection<? extends BlackboardArtifact> nodeArtifacts = lookup.lookupAll(BlackboardArtifact.class); return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT);
if (!nodeArtifacts.isEmpty()) {
BlackboardArtifact originalArtifact = nodeArtifacts.iterator().next();
if ((originalArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| originalArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& underlyingContent.getId() == originalArtifact.getParent().getId()) {
contentArtifacts.add(originalArtifact);
}
} }
if (contentArtifacts.isEmpty()) {
// Get all of the blackboard artifacts associated with the content. These are what this
// viewer displays.
contentArtifacts = underlyingContent.getAllArtifacts();
}
} catch (TskException ex) {
logger.log(Level.SEVERE, "Couldn't get artifacts", ex); //NON-NLS
return new ViewUpdate(getArtifactContents().size(), currentPage, ERROR_TEXT);
} }
} }
@ -543,7 +528,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
// Build the new artifact contents cache. // Build the new artifact contents cache.
ArrayList<BlackboardArtifact> artifactContents = new ArrayList<>(); ArrayList<BlackboardArtifact> artifactContents = new ArrayList<>();
for (BlackboardArtifact artifact : contentArtifacts) { for (BlackboardArtifact artifact : artifacts) {
artifactContents.add(artifact); artifactContents.add(artifact);
} }
@ -552,7 +537,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
int index = 0; int index = 0;
BlackboardArtifact artifact = lookup.lookup(BlackboardArtifact.class); BlackboardArtifact artifact = lookup.lookup(BlackboardArtifact.class);
if (artifact != null) { if (artifact != null) {
index = contentArtifacts.indexOf(artifact); index = artifacts.indexOf(artifact);
if (index == -1) { if (index == -1) {
index = 0; index = 0;
} else { } else {
@ -562,9 +547,9 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat
if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) { if (attr.getAttributeType().getTypeID() == BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT.getTypeID()) {
long assocArtifactId = attr.getValueLong(); long assocArtifactId = attr.getValueLong();
int assocArtifactIndex = -1; int assocArtifactIndex = -1;
for (BlackboardArtifact art : contentArtifacts) { for (BlackboardArtifact art : artifacts) {
if (assocArtifactId == art.getArtifactID()) { if (assocArtifactId == art.getArtifactID()) {
assocArtifactIndex = contentArtifacts.indexOf(art); assocArtifactIndex = artifacts.indexOf(art);
break; break;
} }
} }

View File

@ -44,10 +44,8 @@ import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer; import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import static org.sleuthkit.autopsy.corecomponents.Bundle.*; import static org.sleuthkit.autopsy.corecomponents.Bundle.*;
import org.sleuthkit.autopsy.coreutils.FileUtil; import org.sleuthkit.autopsy.coreutils.FileUtil;
import org.sleuthkit.autopsy.datamodel.BlackboardArtifactNode;
import org.sleuthkit.autopsy.datamodel.ContentUtils; import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.datamodel.DataConversion; import org.sleuthkit.autopsy.datamodel.DataConversion;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
@ -608,24 +606,7 @@ public class DataContentViewerHex extends javax.swing.JPanel implements DataCont
return false; return false;
} }
Content content = DataContentViewerUtility.getDefaultContent(node); Content content = DataContentViewerUtility.getDefaultContent(node);
if (content == null || content.getSize() <= 0) { return content != null && content.getSize() > 0;
return false;
} else if (node instanceof BlackboardArtifactNode) {
BlackboardArtifact theArtifact = ((BlackboardArtifactNode) node).getArtifact();
//disable the content viewer when a download or cached file does not exist instead of displaying its parent
try {
if ((theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID()
|| theArtifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE.getTypeID())
&& content.getId() == theArtifact.getParent().getId()) {
return false;
}
} catch (TskCoreException ex) {
logger.log(Level.WARNING, String.format("Error getting parent of artifact with type %s and objID = %d can not confirm content with name %s and objId = %d is not the parent. Hex content viewer will not be supported.",
theArtifact.getArtifactTypeName(), theArtifact.getObjectID(), content.getName(), content.getId()), ex);
return false;
}
}
return true;
} }
@Override @Override

View File

@ -1,3 +1,7 @@
# {0} - month abbreviation
# {1} - day of month
# {2} - year
DiscoveryAttributes.ActivityDateGroupKey.getDisplayNameTemplate=Week of {0} {1}, {2}
DiscoveryAttributes.GroupingAttributeType.datasource.displayName=Data Source DiscoveryAttributes.GroupingAttributeType.datasource.displayName=Data Source
DiscoveryAttributes.GroupingAttributeType.fileType.displayName=File Type DiscoveryAttributes.GroupingAttributeType.fileType.displayName=File Type
DiscoveryAttributes.GroupingAttributeType.firstDate.displayName=First Activity Date DiscoveryAttributes.GroupingAttributeType.firstDate.displayName=First Activity Date
@ -20,16 +24,11 @@ DiscoveryKeyUtils.DataSourceGroupKey.datasourceAndID={0}(ID: {1})
# {0} - Data source ID # {0} - Data source ID
DiscoveryKeyUtils.DataSourceGroupKey.idOnly=Data source (ID: {0}) DiscoveryKeyUtils.DataSourceGroupKey.idOnly=Data source (ID: {0})
DiscoveryKeyUtils.FileTagGroupKey.noSets=None DiscoveryKeyUtils.FileTagGroupKey.noSets=None
DiscoveryKeyUtils.FirstActivityDateGroupKey.noDate=No Date Available
DiscoveryKeyUtils.HashHitsGroupKey.noHashHits=None DiscoveryKeyUtils.HashHitsGroupKey.noHashHits=None
DiscoveryKeyUtils.InterestingItemGroupKey.noSets=None DiscoveryKeyUtils.InterestingItemGroupKey.noSets=None
DiscoveryKeyUtils.KeywordListGroupKey.noKeywords=None DiscoveryKeyUtils.KeywordListGroupKey.noKeywords=None
DiscoveryKeyUtils.LastActivityDateGroupKey.noDate=No Date Available
DiscoveryKeyUtils.NoGroupingGroupKey.allFiles=All Files DiscoveryKeyUtils.NoGroupingGroupKey.allFiles=All Files
DiscoveryKeyUtils.ObjectDetectedGroupKey.noSets=None DiscoveryKeyUtils.ObjectDetectedGroupKey.noSets=None
# {0} - totalVisits
DiscoveryKeyUtils.PageViewsGroupKey.displayName={0} page views
DiscoveryKeyUtils.PageViewsGroupKey.noVisits=No page views
# {0} - domain # {0} - domain
# {1} - artifactType # {1} - artifactType
DomainSearchArtifactsRequest.toString.text=Domain: {0} ArtifactType: {1} DomainSearchArtifactsRequest.toString.text=Domain: {0} ArtifactType: {1}
@ -94,6 +93,10 @@ SearchData.Frequency.unique.displayName=Unique (1)
SearchData.Frequency.unknown.displayName=Unknown SearchData.Frequency.unknown.displayName=Unknown
SearchData.Frequency.verycommon.displayName=Very Common (100+) SearchData.Frequency.verycommon.displayName=Very Common (100+)
SearchData.notPrevNotable.displayName=Previously Not Notable SearchData.notPrevNotable.displayName=Previously Not Notable
SearchData.PageViews.over1000=1000+ page views
# {0} - minValue
# {1} - maxValue
SearchData.PageViews.rangeTemplate={0}-{1} page views
SearchData.prevNotable.displayName=Previously Notable SearchData.prevNotable.displayName=Previously Notable
SearchData.Score.interesting.displayName=Interesting SearchData.Score.interesting.displayName=Interesting
SearchData.Score.notable.displayName=Notable SearchData.Score.notable.displayName=Notable

View File

@ -986,9 +986,9 @@ public class DiscoveryAttributes {
*/ */
public static List<GroupingAttributeType> getOptionsForGroupingForDomains() { public static List<GroupingAttributeType> getOptionsForGroupingForDomains() {
if (CentralRepository.isEnabled()) { if (CentralRepository.isEnabled()) {
return Arrays.asList(FREQUENCY, LAST_ACTIVITY_DATE, FIRST_ACTIVITY_DATE, PAGE_VIEWS, PREVIOUSLY_NOTABLE, DOMAIN_CATEGORY); return Arrays.asList(PAGE_VIEWS, FREQUENCY, LAST_ACTIVITY_DATE, FIRST_ACTIVITY_DATE, PREVIOUSLY_NOTABLE, DOMAIN_CATEGORY);
} else { } else {
return Arrays.asList(LAST_ACTIVITY_DATE, FIRST_ACTIVITY_DATE, PAGE_VIEWS, DOMAIN_CATEGORY); return Arrays.asList(PAGE_VIEWS, LAST_ACTIVITY_DATE, FIRST_ACTIVITY_DATE, DOMAIN_CATEGORY);
} }
} }
} }

View File

@ -18,17 +18,21 @@
*/ */
package org.sleuthkit.autopsy.discovery.search; package org.sleuthkit.autopsy.discovery.search;
import java.text.SimpleDateFormat; import java.time.DayOfWeek;
import java.time.Instant;
import java.time.ZonedDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.Collections; import java.util.Collections;
import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.TimeUnit; import java.util.TimeZone;
import java.util.logging.Level; import java.util.logging.Level;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.discovery.search.SearchData.PageViews;
import org.sleuthkit.autopsy.discovery.ui.MonthAbbreviation;
import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
@ -1133,29 +1137,34 @@ public class DiscoveryKeyUtils {
*/ */
static class LastActivityDateGroupKey extends GroupKey { static class LastActivityDateGroupKey extends GroupKey {
private final Long epochDate; private ZonedDateTime currentWeekCutOff;
private final String dateNameString;
/** /**
* Construct a new LastActivityDateGroupKey. * Construct a new LastActivityDateGroupKey.
* *
* @param result The Result to create the group key for. * @param result The Result to create the group key for.
*/ */
@NbBundle.Messages({
"DiscoveryKeyUtils.LastActivityDateGroupKey.noDate=No Date Available"})
LastActivityDateGroupKey(Result result) { LastActivityDateGroupKey(Result result) {
if (result instanceof ResultDomain) { if (result instanceof ResultDomain) {
epochDate = ((ResultDomain) result).getActivityEnd(); ResultDomain domainResult = ((ResultDomain) result);
dateNameString = new SimpleDateFormat("yyyy/MM/dd", Locale.getDefault()).format(new Date(TimeUnit.SECONDS.toMillis(epochDate))); currentWeekCutOff = getCurrentWeekCutOff(domainResult.getActivityEnd(), domainResult);
} else { } else {
epochDate = Long.MAX_VALUE; throw new IllegalArgumentException("Expected a domain result only.");
dateNameString = Bundle.DiscoveryKeyUtils_LastActivityDateGroupKey_noDate();
} }
} }
@NbBundle.Messages({
"# {0} - month abbreviation",
"# {1} - day of month",
"# {2} - year",
"DiscoveryAttributes.ActivityDateGroupKey.getDisplayNameTemplate=Week of {0} {1}, {2}"
})
@Override @Override
String getDisplayName() { String getDisplayName() {
return getDateNameString(); MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(currentWeekCutOff.getMonthValue());
return Bundle.DiscoveryAttributes_ActivityDateGroupKey_getDisplayNameTemplate(
currentCutOffMonth.toString(), Integer.toString(currentWeekCutOff.getDayOfMonth()),
Integer.toString(currentWeekCutOff.getYear()));
} }
@Override @Override
@ -1169,53 +1178,40 @@ public class DiscoveryKeyUtils {
} }
LastActivityDateGroupKey dateGroupKey = (LastActivityDateGroupKey) otherKey; LastActivityDateGroupKey dateGroupKey = (LastActivityDateGroupKey) otherKey;
return getDateNameString().equals(dateGroupKey.getDateNameString()); return getDisplayName().equals(dateGroupKey.getDisplayName());
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(getDateNameString()); return Objects.hash(getDisplayName());
} }
@Override @Override
public int compareTo(GroupKey otherGroupKey) { public int compareTo(GroupKey otherGroupKey) {
if (otherGroupKey instanceof LastActivityDateGroupKey) { if (otherGroupKey instanceof LastActivityDateGroupKey) {
LastActivityDateGroupKey otherDateGroupKey = (LastActivityDateGroupKey) otherGroupKey; LastActivityDateGroupKey otherDateGroupKey = (LastActivityDateGroupKey) otherGroupKey;
return Long.compare(otherDateGroupKey.currentWeekCutOff.toEpochSecond(), currentWeekCutOff.toEpochSecond());
// Put the empty list at the end
if (this.getEpochDate().equals(Long.MAX_VALUE)) {
if (otherDateGroupKey.getEpochDate().equals(Long.MAX_VALUE)) {
return 0;
} else {
return 1;
}
} else if (otherDateGroupKey.getEpochDate().equals(Long.MAX_VALUE)) {
return -1;
}
return getDateNameString().compareTo(otherDateGroupKey.getDateNameString());
} else { } else {
return compareClassNames(otherGroupKey); return compareClassNames(otherGroupKey);
} }
} }
}
/**
* Get the date this group is for as a Long. /**
* * Get the next closed Sunday given an epoch time and timezone.
* @return The date. * Dates for grouping are managed on a weekly basis. Each Sunday
*/ * acts as the boundary and representative for the week.
Long getEpochDate() { */
return epochDate; private static ZonedDateTime getCurrentWeekCutOff(long epochSeconds, ResultDomain domainResult) {
} Instant startActivityAsInsant = Instant.ofEpochSecond(epochSeconds);
// Determines the timezone using the settings panel or value parsed from the
/** // parent data source
* Get the name which identifies this group. TimeZone currentTimeZone = ContentUtils.getTimeZone(domainResult.getDataSource());
* // Convert to a datetime using epoch and timezone.
* @return The dateNameString. ZonedDateTime startActivityAsDateTime = ZonedDateTime.ofInstant(startActivityAsInsant, currentTimeZone.toZoneId());
*/ // Get the closest Sunday, which is the cut off for the current week.
String getDateNameString() { // Use this cut off to perform grouping and comparing.
return dateNameString; return startActivityAsDateTime.with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
}
} }
/** /**
@ -1223,29 +1219,28 @@ public class DiscoveryKeyUtils {
*/ */
static class FirstActivityDateGroupKey extends GroupKey { static class FirstActivityDateGroupKey extends GroupKey {
private final Long epochDate; private ZonedDateTime currentWeekCutOff;
private final String dateNameString;
/** /**
* Construct a new FirstActivityDateGroupKey. * Construct a new FirstActivityDateGroupKey.
* *
* @param result The Result to create the group key for. * @param result The Result to create the group key for.
*/ */
@NbBundle.Messages({
"DiscoveryKeyUtils.FirstActivityDateGroupKey.noDate=No Date Available"})
FirstActivityDateGroupKey(Result result) { FirstActivityDateGroupKey(Result result) {
if (result instanceof ResultDomain) { if (result instanceof ResultDomain) {
epochDate = ((ResultDomain) result).getActivityStart(); ResultDomain domainResult = ((ResultDomain) result);
dateNameString = new SimpleDateFormat("yyyy/MM/dd", Locale.getDefault()).format(new Date(TimeUnit.SECONDS.toMillis(epochDate))); currentWeekCutOff = getCurrentWeekCutOff(domainResult.getActivityStart(), domainResult);
} else { } else {
epochDate = Long.MAX_VALUE; throw new IllegalArgumentException("Expected a domain result only.");
dateNameString = Bundle.DiscoveryKeyUtils_FirstActivityDateGroupKey_noDate();
} }
} }
@Override @Override
String getDisplayName() { String getDisplayName() {
return getDateNameString(); MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(currentWeekCutOff.getMonthValue());
return Bundle.DiscoveryAttributes_ActivityDateGroupKey_getDisplayNameTemplate(
currentCutOffMonth.toString(), Integer.toString(currentWeekCutOff.getDayOfMonth()),
Integer.toString(currentWeekCutOff.getYear()));
} }
@Override @Override
@ -1259,53 +1254,23 @@ public class DiscoveryKeyUtils {
} }
FirstActivityDateGroupKey dateGroupKey = (FirstActivityDateGroupKey) otherKey; FirstActivityDateGroupKey dateGroupKey = (FirstActivityDateGroupKey) otherKey;
return getDateNameString().equals(dateGroupKey.getDateNameString()); return getDisplayName().equals(dateGroupKey.getDisplayName());
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(getDateNameString()); return Objects.hash(getDisplayName());
} }
@Override @Override
public int compareTo(GroupKey otherGroupKey) { public int compareTo(GroupKey otherGroupKey) {
if (otherGroupKey instanceof FirstActivityDateGroupKey) { if (otherGroupKey instanceof FirstActivityDateGroupKey) {
FirstActivityDateGroupKey otherDateGroupKey = (FirstActivityDateGroupKey) otherGroupKey; FirstActivityDateGroupKey otherDateGroupKey = (FirstActivityDateGroupKey) otherGroupKey;
return Long.compare(otherDateGroupKey.currentWeekCutOff.toEpochSecond(), currentWeekCutOff.toEpochSecond());
// Put the empty list at the end
if (this.getEpochDate().equals(Long.MAX_VALUE)) {
if (otherDateGroupKey.getEpochDate().equals(Long.MAX_VALUE)) {
return 0;
} else {
return 1;
}
} else if (otherDateGroupKey.getEpochDate().equals(Long.MAX_VALUE)) {
return -1;
}
return getDateNameString().compareTo(otherDateGroupKey.getDateNameString());
} else { } else {
return compareClassNames(otherGroupKey); return compareClassNames(otherGroupKey);
} }
} }
/**
* Get the date this group is for as a Long.
*
* @return The date.
*/
Long getEpochDate() {
return epochDate;
}
/**
* Get the name which identifies this group.
*
* @return The dateNameString.
*/
String getDateNameString() {
return dateNameString;
}
} }
/** /**
@ -1316,28 +1281,23 @@ public class DiscoveryKeyUtils {
static class PageViewsGroupKey extends GroupKey { static class PageViewsGroupKey extends GroupKey {
private final String displayName; private final String displayName;
private final Long pageViews; private final PageViews pageViews;
/** /**
* Construct a new NumberOfVisitsGroupKey. * Construct a new NumberOfVisitsGroupKey.
* *
* @param result The Result to create the group key for. * @param result The Result to create the group key for.
*/ */
@NbBundle.Messages({
"# {0} - totalVisits",
"DiscoveryKeyUtils.PageViewsGroupKey.displayName={0} page views",
"DiscoveryKeyUtils.PageViewsGroupKey.noVisits=No page views"})
PageViewsGroupKey(Result result) { PageViewsGroupKey(Result result) {
if (result instanceof ResultDomain) { if (result instanceof ResultDomain) {
Long totalPageViews = ((ResultDomain) result).getTotalPageViews(); Long totalPageViews = ((ResultDomain) result).getTotalPageViews();
if (totalPageViews == null) { if (totalPageViews == null) {
totalPageViews = 0L; totalPageViews = 0L;
} }
pageViews = totalPageViews; pageViews = PageViews.fromPageViewCount(totalPageViews);
displayName = Bundle.DiscoveryKeyUtils_PageViewsGroupKey_displayName(Long.toString(pageViews)); displayName = pageViews.toString();
} else { } else {
displayName = Bundle.DiscoveryKeyUtils_PageViewsGroupKey_noVisits(); throw new IllegalArgumentException("Expected a domain instance only.");
pageViews = -1L;
} }
} }
@ -1356,7 +1316,7 @@ public class DiscoveryKeyUtils {
* *
* @return The number of page views this group is for. * @return The number of page views this group is for.
*/ */
Long getPageViews() { PageViews getPageViews() {
return pageViews; return pageViews;
} }
@ -1378,7 +1338,7 @@ public class DiscoveryKeyUtils {
public int compareTo(GroupKey otherGroupKey) { public int compareTo(GroupKey otherGroupKey) {
if (otherGroupKey instanceof PageViewsGroupKey) { if (otherGroupKey instanceof PageViewsGroupKey) {
PageViewsGroupKey pageViewsKey = (PageViewsGroupKey) otherGroupKey; PageViewsGroupKey pageViewsKey = (PageViewsGroupKey) otherGroupKey;
return Long.compare(getPageViews(), pageViewsKey.getPageViews()); return getPageViews().compareTo(pageViewsKey.getPageViews());
} else { } else {
return compareClassNames(otherGroupKey); return compareClassNames(otherGroupKey);
} }

View File

@ -24,12 +24,15 @@ import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.TimeZone;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository; import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey; import org.sleuthkit.autopsy.discovery.search.DiscoveryKeyUtils.GroupKey;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TimeUtilities;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
/** /**
@ -245,7 +248,8 @@ public class DomainSearch {
private String getDate(BlackboardArtifact artifact) throws TskCoreException { private String getDate(BlackboardArtifact artifact) throws TskCoreException {
for (BlackboardAttribute attribute : artifact.getAttributes()) { for (BlackboardAttribute attribute : artifact.getAttributes()) {
if (attribute.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) { if (attribute.getAttributeType().getTypeName().startsWith("TSK_DATETIME")) {
String dateString = attribute.getDisplayString(); TimeZone timeZone = ContentUtils.getTimeZone(artifact);
String dateString = TimeUtilities.epochToTime(attribute.getValueLong(), timeZone);
if (dateString.length() >= 10) { if (dateString.length() >= 10) {
return dateString.substring(0, 10); return dateString.substring(0, 10);
} }

View File

@ -212,13 +212,14 @@ class DomainSearchCacheLoader extends CacheLoader<SearchKey, Map<GroupKey, List<
final StringJoiner whereClause = new StringJoiner(" OR "); final StringJoiner whereClause = new StringJoiner(" OR ");
final StringJoiner havingClause = new StringJoiner(" AND "); final StringJoiner havingClause = new StringJoiner(" AND ");
String artifactTypeFilter = null; // Capture all types by default.
ArtifactTypeFilter artifactTypeFilter = new ArtifactTypeFilter(SearchData.Type.DOMAIN.getArtifactTypes());
boolean hasDateTimeFilter = false; boolean hasDateTimeFilter = false;
for (AbstractFilter filter : filters) { for (AbstractFilter filter : filters) {
if (filter instanceof ArtifactTypeFilter) { if (filter instanceof ArtifactTypeFilter) {
artifactTypeFilter = ((ArtifactTypeFilter) filter) // Replace with user defined types.
.getWhereClause(Arrays.asList(TSK_WEB_ACCOUNT_TYPE)); artifactTypeFilter = ((ArtifactTypeFilter) filter);
} else if (!(filter instanceof DataSourceFilter) && !filter.useAlternateFilter()) { } else if (!(filter instanceof DataSourceFilter) && !filter.useAlternateFilter()) {
if (filter instanceof ArtifactDateRangeFilter) { if (filter instanceof ArtifactDateRangeFilter) {
hasDateTimeFilter = true; hasDateTimeFilter = true;
@ -240,7 +241,7 @@ class DomainSearchCacheLoader extends CacheLoader<SearchKey, Map<GroupKey, List<
havingClause.add("SUM(CASE WHEN " + domainAttributeFilter + " THEN 1 ELSE 0 END) > 0"); havingClause.add("SUM(CASE WHEN " + domainAttributeFilter + " THEN 1 ELSE 0 END) > 0");
return Pair.of( return Pair.of(
whereClause.toString() + ((artifactTypeFilter != null) ? " AND (" + artifactTypeFilter + ")" : ""), whereClause.toString() + " AND (" + artifactTypeFilter.getWhereClause(Arrays.asList(TSK_WEB_ACCOUNT_TYPE)) + ")",
havingClause.toString() havingClause.toString()
); );
} }

View File

@ -151,7 +151,7 @@ public class ResultDomain extends Result {
} }
@Override @Override
public Content getDataSource() throws TskCoreException { public Content getDataSource() {
return this.dataSource; return this.dataSource;
} }

View File

@ -36,7 +36,13 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
public final class SearchData { public final class SearchData {
private final static long BYTES_PER_MB = 1000000; private final static long BYTES_PER_MB = 1000000;
private static final Set<BlackboardArtifact.ARTIFACT_TYPE> DOMAIN_ARTIFACT_TYPES = EnumSet.of(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY, BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY); private static final Set<BlackboardArtifact.ARTIFACT_TYPE> DOMAIN_ARTIFACT_TYPES =
EnumSet.of(BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK,
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_CACHE,
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE,
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD,
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY,
BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY);
/** /**
@ -67,6 +73,62 @@ public final class SearchData {
return displayName; return displayName;
} }
} }
/**
* Enum representing the number of page views a domain has received. Page
* views a grouped into ranges for cleaner display and management.
*/
@NbBundle.Messages({
"# {0} - minValue",
"# {1} - maxValue",
"SearchData.PageViews.rangeTemplate={0}-{1} page views",
"SearchData.PageViews.over1000=1000+ page views"
})
public enum PageViews {
OVER_1000(1001, Long.MAX_VALUE), // ranking, minValue, maxValue
UP_TO_1000(501, 1000),
UP_TO_500(101, 500),
UP_TO_100(51, 100),
UP_TO_50(11, 50),
UP_TO_10(0, 10);
private final long minValue;
private final long maxValue;
PageViews(long minValue, long maxValue) {
this.maxValue = maxValue;
this.minValue = minValue;
}
@Override
public String toString() {
if (this == PageViews.OVER_1000) {
return Bundle.SearchData_PageViews_over1000();
} else {
return Bundle.SearchData_PageViews_rangeTemplate(Long.toString(minValue), Long.toString(maxValue));
}
}
/**
* Determines if the given count is covered by this PageView interval.
*/
boolean covers(long count) {
return count >= minValue && count <= maxValue;
}
/**
* Utility to fetch the appropriate PageView interval for the given count.
*/
public static PageViews fromPageViewCount(long count) {
for (PageViews view : PageViews.values()) {
if (view.covers(count)) {
return view;
}
}
return null;
}
}
/** /**
* Enum representing how often the result occurs in the Central Repository. * Enum representing how often the result occurs in the Central Repository.
*/ */

View File

@ -33,6 +33,7 @@ import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.datamodel.TskCoreException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
@ -206,7 +207,7 @@ public class SearchFiltering {
*/ */
public static class ArtifactTypeFilter extends AbstractFilter { public static class ArtifactTypeFilter extends AbstractFilter {
private final List<ARTIFACT_TYPE> types; private final Collection<ARTIFACT_TYPE> types;
/** /**
* Construct a new ArtifactTypeFilter. * Construct a new ArtifactTypeFilter.
@ -214,7 +215,7 @@ public class SearchFiltering {
* @param types The list of BlackboardArtifact types to include in * @param types The list of BlackboardArtifact types to include in
* results from. * results from.
*/ */
public ArtifactTypeFilter(List<ARTIFACT_TYPE> types) { public ArtifactTypeFilter(Collection<ARTIFACT_TYPE> types) {
this.types = types; this.types = types;
} }
@ -223,8 +224,8 @@ public class SearchFiltering {
* *
* @return The list of artifact types specified by the filter. * @return The list of artifact types specified by the filter.
*/ */
public List<ARTIFACT_TYPE> getTypes() { public Collection<ARTIFACT_TYPE> getTypes() {
return Collections.unmodifiableList(types); return Collections.unmodifiableCollection(types);
} }
private StringJoiner joinStandardArtifactTypes() { private StringJoiner joinStandardArtifactTypes() {

View File

@ -77,7 +77,22 @@ MiniTimelineArtifactListPanel.value.noValue=No value available.
MiniTimelineDateListPanel.countColumn.name=Count MiniTimelineDateListPanel.countColumn.name=Count
MiniTimelineDateListPanel.dateColumn.name=Date MiniTimelineDateListPanel.dateColumn.name=Date
MiniTimelineDateListPanel.value.noValue=No value available. MiniTimelineDateListPanel.value.noValue=No value available.
<<<<<<< HEAD
MiniTimelinePanel.loadingPanel.details=the Mini Timeline view MiniTimelinePanel.loadingPanel.details=the Mini Timeline view
=======
MonthAbbreviation.aprilAbbrev=Apr
MonthAbbreviation.augustAbbrev=Aug
MonthAbbreviation.decemberAbbrev=Dec
MonthAbbreviation.feburaryAbbrev=Feb
MonthAbbreviation.januraryAbbrev=Jan
MonthAbbreviation.julyAbbrev=Jul
MonthAbbreviation.juneAbbrev=Jun
MonthAbbreviation.marchAbbrev=Mar
MonthAbbreviation.mayAbbrev=May
MonthAbbreviation.novemberAbbrev=Nov
MonthAbbreviation.octoberAbbrev=Oct
MonthAbbreviation.septemberAbbrev=Sep
>>>>>>> 1dd895dc72ac6e7c796a9883a2c790b46c27c47c
ObjectDetectedFilterPanel.error.text=At least one object type name must be selected. ObjectDetectedFilterPanel.error.text=At least one object type name must be selected.
ParentFolderFilterPanel.error.text=At least one parent path must be entered. ParentFolderFilterPanel.error.text=At least one parent path must be entered.
PastOccurrencesFilterPanel.error.text=At least one value in the past occurrence filter must be selected. PastOccurrencesFilterPanel.error.text=At least one value in the past occurrence filter must be selected.

View File

@ -22,15 +22,16 @@ import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Point; import java.awt.Point;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.text.SimpleDateFormat; import java.time.Instant;
import java.util.Date; import java.time.ZonedDateTime;
import java.util.Locale; import java.util.TimeZone;
import javax.swing.ImageIcon; import javax.swing.ImageIcon;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.ListCellRenderer; import javax.swing.ListCellRenderer;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.coreutils.ThreadConfined; import org.sleuthkit.autopsy.coreutils.ThreadConfined;
import org.sleuthkit.autopsy.datamodel.ContentUtils;
/** /**
* Class which displays a preview and details about a domain. * Class which displays a preview and details about a domain.
@ -39,7 +40,6 @@ class DomainSummaryPanel extends javax.swing.JPanel implements ListCellRenderer<
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private static final Color SELECTION_COLOR = new Color(0, 120, 215); private static final Color SELECTION_COLOR = new Color(0, 120, 215);
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MMM dd yyyy", Locale.getDefault());
/** /**
* Creates new form DomainPanel. * Creates new form DomainPanel.
@ -149,8 +149,9 @@ class DomainSummaryPanel extends javax.swing.JPanel implements ListCellRenderer<
@Override @Override
public Component getListCellRendererComponent(JList<? extends DomainWrapper> list, DomainWrapper value, int index, boolean isSelected, boolean cellHasFocus) { public Component getListCellRendererComponent(JList<? extends DomainWrapper> list, DomainWrapper value, int index, boolean isSelected, boolean cellHasFocus) {
domainNameLabel.setText(value.getResultDomain().getDomain()); domainNameLabel.setText(value.getResultDomain().getDomain());
String startDate = dateFormat.format(new Date(value.getResultDomain().getActivityStart() * 1000)); TimeZone timeZone = ContentUtils.getTimeZone(value.getResultDomain().getDataSource());
String endDate = dateFormat.format(new Date(value.getResultDomain().getActivityEnd() * 1000)); String startDate = formatDate(value.getResultDomain().getActivityStart(), timeZone);
String endDate = formatDate(value.getResultDomain().getActivityEnd(), timeZone);
activityLabel.setText(Bundle.DomainSummaryPanel_activity_text(startDate, endDate)); activityLabel.setText(Bundle.DomainSummaryPanel_activity_text(startDate, endDate));
totalVisitsLabel.setText(Bundle.DomainSummaryPanel_totalPages_text() + value.getResultDomain().getTotalPageViews()); totalVisitsLabel.setText(Bundle.DomainSummaryPanel_totalPages_text() + value.getResultDomain().getTotalPageViews());
pagesLabel.setText(Bundle.DomainSummaryPanel_pages_text() + value.getResultDomain().getPageViewsInLast60Days()); pagesLabel.setText(Bundle.DomainSummaryPanel_pages_text() + value.getResultDomain().getPageViewsInLast60Days());
@ -165,6 +166,22 @@ class DomainSummaryPanel extends javax.swing.JPanel implements ListCellRenderer<
setBackground(isSelected ? SELECTION_COLOR : list.getBackground()); setBackground(isSelected ? SELECTION_COLOR : list.getBackground());
return this; return this;
} }
/**
* Formats an epoch time in a given time zone using the following pattern
*
* MMM dd YYYY
*
* The pattern below is formatted manually to reuse the MonthAbbreviation utility.
*/
private String formatDate(long epochSeconds, TimeZone timeZone) {
Instant epochSecondsAsInstant = Instant.ofEpochSecond(epochSeconds);
ZonedDateTime dateTime = ZonedDateTime.ofInstant(epochSecondsAsInstant, timeZone.toZoneId());
MonthAbbreviation currentCutOffMonth = MonthAbbreviation.fromMonthValue(dateTime.getMonthValue());
return String.format("%s %02d %04d",
currentCutOffMonth.toString(),
dateTime.getDayOfMonth(), dateTime.getYear());
}
@ThreadConfined(type = ThreadConfined.ThreadType.AWT) @ThreadConfined(type = ThreadConfined.ThreadType.AWT)
@Override @Override

View File

@ -0,0 +1,80 @@
/*
* Autopsy
*
* Copyright 2020 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.discovery.ui;
import org.openide.util.NbBundle;
/**
* Utility for representing month abbreviations
*/
@NbBundle.Messages({
"MonthAbbreviation.januraryAbbrev=Jan",
"MonthAbbreviation.feburaryAbbrev=Feb",
"MonthAbbreviation.marchAbbrev=Mar",
"MonthAbbreviation.aprilAbbrev=Apr",
"MonthAbbreviation.mayAbbrev=May",
"MonthAbbreviation.juneAbbrev=Jun",
"MonthAbbreviation.julyAbbrev=Jul",
"MonthAbbreviation.augustAbbrev=Aug",
"MonthAbbreviation.septemberAbbrev=Sep",
"MonthAbbreviation.octoberAbbrev=Oct",
"MonthAbbreviation.novemberAbbrev=Nov",
"MonthAbbreviation.decemberAbbrev=Dec"
})
public enum MonthAbbreviation {
JANURARY(Bundle.MonthAbbreviation_januraryAbbrev()),
FEBURARY(Bundle.MonthAbbreviation_feburaryAbbrev()),
MARCH(Bundle.MonthAbbreviation_marchAbbrev()),
APRIL(Bundle.MonthAbbreviation_aprilAbbrev()),
MAY(Bundle.MonthAbbreviation_mayAbbrev()),
JUNE(Bundle.MonthAbbreviation_juneAbbrev()),
JULY(Bundle.MonthAbbreviation_julyAbbrev()),
AUGUST(Bundle.MonthAbbreviation_augustAbbrev()),
SEPTEMBER(Bundle.MonthAbbreviation_septemberAbbrev()),
OCTOBER(Bundle.MonthAbbreviation_octoberAbbrev()),
NOVEMBER(Bundle.MonthAbbreviation_novemberAbbrev()),
DECEMBER(Bundle.MonthAbbreviation_decemberAbbrev());
private final String abbreviation;
MonthAbbreviation(String abbreviation) {
this.abbreviation = abbreviation;
}
@Override
public String toString() {
return this.abbreviation;
}
/**
* Converts a month value (1-12) to the appropriate abbreviation.
*
* @param value Month value (1-12).
* @return Abbreviation matching the month value, null if not found.
*/
public static MonthAbbreviation fromMonthValue(int value) {
MonthAbbreviation[] months = MonthAbbreviation.values();
for(int i = 0; i < months.length; i++) {
if (i + 1 == value) {
return months[i];
}
}
return null;
}
}

View File

@ -210,7 +210,6 @@ KeywordSearchJobSettingsPanel.languagesLabel.text=Scripts enabled for string ext
KeywordSearchGlobalLanguageSettingsPanel.enableUTF8Checkbox.text=Enable UTF8 text extraction KeywordSearchGlobalLanguageSettingsPanel.enableUTF8Checkbox.text=Enable UTF8 text extraction
KeywordSearchGlobalLanguageSettingsPanel.ingestSettingsLabel.text=Ingest settings for string extraction from unknown file types (changes effective on next ingest): KeywordSearchGlobalLanguageSettingsPanel.ingestSettingsLabel.text=Ingest settings for string extraction from unknown file types (changes effective on next ingest):
KeywordSearchGlobalLanguageSettingsPanel.enableUTF16Checkbox.text=Enable UTF16LE and UTF16BE string extraction KeywordSearchGlobalLanguageSettingsPanel.enableUTF16Checkbox.text=Enable UTF16LE and UTF16BE string extraction
KeywordSearchGlobalLanguageSettingsPanel.enableOcrCheckbox.text=Enable Optical Character Recognition (OCR)
KeywordSearchGlobalLanguageSettingsPanel.languagesLabel.text=Enabled scripts (languages): KeywordSearchGlobalLanguageSettingsPanel.languagesLabel.text=Enabled scripts (languages):
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.toolTipText=20 mins. (fastest ingest time) KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.toolTipText=20 mins. (fastest ingest time)
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.text=20 minutes (slowest feedback, fastest ingest) KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.text=20 minutes (slowest feedback, fastest ingest)
@ -320,3 +319,4 @@ ExtractedContentPanel.pageTotalLabel.text=-
ExtractedContentPanel.pageOfLabel.text=of ExtractedContentPanel.pageOfLabel.text=of
ExtractedContentPanel.pageCurLabel.text=- ExtractedContentPanel.pageCurLabel.text=-
ExtractedContentPanel.pagesLabel.text=Page: ExtractedContentPanel.pagesLabel.text=Page:
KeywordSearchGlobalSearchSettingsPanel.ocrCheckBox.text=Enable Optical Character Recognition (OCR)

View File

@ -18,6 +18,8 @@ GlobalEditListPanel.warning.title=Warning
IndexedText.errorMessage.errorGettingText=<span style='font-style:italic'>Error retrieving indexed text.</span> IndexedText.errorMessage.errorGettingText=<span style='font-style:italic'>Error retrieving indexed text.</span>
IndexedText.warningMessage.knownFile=<span style='font-style:italic'>This file is a known file (based on MD5 hash) and does not have indexed text.</span> IndexedText.warningMessage.knownFile=<span style='font-style:italic'>This file is a known file (based on MD5 hash) and does not have indexed text.</span>
IndexedText.warningMessage.noTextAvailable=<span style='font-style:italic'>No indexed text for this file.</span> IndexedText.warningMessage.noTextAvailable=<span style='font-style:italic'>No indexed text for this file.</span>
KeywordSearchGlobalLanguageSettingsPanel.enableOcrCheckbox.text=Enable Optical Character Recognition (OCR)
KeywordSearchGlobalSearchSettingsPanel.customizeComponents.windowsOCR=Enable Optical Character Recognition (OCR) (Requires Windows 64-bit)
KeywordSearchGlobalSettingsPanel.Title=Global Keyword Search Settings KeywordSearchGlobalSettingsPanel.Title=Global Keyword Search Settings
KeywordSearchIngestModule.init.badInitMsg=Keyword search server was not properly initialized, cannot run keyword search ingest. KeywordSearchIngestModule.init.badInitMsg=Keyword search server was not properly initialized, cannot run keyword search ingest.
# {0} - Reason for not connecting to Solr # {0} - Reason for not connecting to Solr
@ -36,7 +38,7 @@ KeywordSearchResultFactory.createNodeForKey.noResultsFound.text=No results found
KeywordSearchResultFactory.query.exception.msg=Could not perform the query KeywordSearchResultFactory.query.exception.msg=Could not perform the query
OpenIDE-Module-Display-Category=Ingest Module OpenIDE-Module-Display-Category=Ingest Module
OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\n\The module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found. OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\nThe module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found.
OpenIDE-Module-Name=KeywordSearch OpenIDE-Module-Name=KeywordSearch
OptionsCategory_Name_KeywordSearchOptions=Keyword Search OptionsCategory_Name_KeywordSearchOptions=Keyword Search
OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search
@ -254,7 +256,6 @@ KeywordSearchJobSettingsPanel.languagesLabel.text=Scripts enabled for string ext
KeywordSearchGlobalLanguageSettingsPanel.enableUTF8Checkbox.text=Enable UTF8 text extraction KeywordSearchGlobalLanguageSettingsPanel.enableUTF8Checkbox.text=Enable UTF8 text extraction
KeywordSearchGlobalLanguageSettingsPanel.ingestSettingsLabel.text=Ingest settings for string extraction from unknown file types (changes effective on next ingest): KeywordSearchGlobalLanguageSettingsPanel.ingestSettingsLabel.text=Ingest settings for string extraction from unknown file types (changes effective on next ingest):
KeywordSearchGlobalLanguageSettingsPanel.enableUTF16Checkbox.text=Enable UTF16LE and UTF16BE string extraction KeywordSearchGlobalLanguageSettingsPanel.enableUTF16Checkbox.text=Enable UTF16LE and UTF16BE string extraction
KeywordSearchGlobalLanguageSettingsPanel.enableOcrCheckbox.text=Enable Optical Character Recognition (OCR)
KeywordSearchGlobalLanguageSettingsPanel.languagesLabel.text=Enabled scripts (languages): KeywordSearchGlobalLanguageSettingsPanel.languagesLabel.text=Enabled scripts (languages):
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.toolTipText=20 mins. (fastest ingest time) KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.toolTipText=20 mins. (fastest ingest time)
KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.text=20 minutes (slowest feedback, fastest ingest) KeywordSearchGlobalSearchSettingsPanel.timeRadioButton1.text=20 minutes (slowest feedback, fastest ingest)
@ -382,6 +383,7 @@ ExtractedContentPanel.pageTotalLabel.text=-
ExtractedContentPanel.pageOfLabel.text=of ExtractedContentPanel.pageOfLabel.text=of
ExtractedContentPanel.pageCurLabel.text=- ExtractedContentPanel.pageCurLabel.text=-
ExtractedContentPanel.pagesLabel.text=Page: ExtractedContentPanel.pagesLabel.text=Page:
KeywordSearchGlobalSearchSettingsPanel.ocrCheckBox.text=Enable Optical Character Recognition (OCR)
TextZoomPanel.zoomInButton.text= TextZoomPanel.zoomInButton.text=
TextZoomPanel.zoomOutButton.text= TextZoomPanel.zoomOutButton.text=
TextZoomPanel.zoomResetButton.text=Reset TextZoomPanel.zoomResetButton.text=Reset

View File

@ -186,7 +186,6 @@ KeywordSearchEditListPanel.selectAllMenuItem.text=\u3059\u3079\u3066\u9078\u629e
KeywordSearchFilterNode.getFileActions.openExternViewActLbl=\u5916\u90e8\u30d3\u30e5\u30fc\u30ef\u30fc\u3067\u958b\u304f Ctrl+E KeywordSearchFilterNode.getFileActions.openExternViewActLbl=\u5916\u90e8\u30d3\u30e5\u30fc\u30ef\u30fc\u3067\u958b\u304f Ctrl+E
KeywordSearchFilterNode.getFileActions.searchSameMd5=\u540c\u3058MD5\u30cf\u30c3\u30b7\u30e5\u3067\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22 KeywordSearchFilterNode.getFileActions.searchSameMd5=\u540c\u3058MD5\u30cf\u30c3\u30b7\u30e5\u3067\u30d5\u30a1\u30a4\u30eb\u3092\u691c\u7d22
KeywordSearchFilterNode.getFileActions.viewInNewWinActionLbl=\u65b0\u3057\u3044\u30a6\u30a3\u30f3\u30c9\u30a6\u3067\u8868\u793a KeywordSearchFilterNode.getFileActions.viewInNewWinActionLbl=\u65b0\u3057\u3044\u30a6\u30a3\u30f3\u30c9\u30a6\u3067\u8868\u793a
KeywordSearchGlobalLanguageSettingsPanel.enableOcrCheckbox.text=\u5149\u5b66\u6587\u5b57\u8a8d\u8b58(OCR)\u3092\u6709\u52b9\u5316
KeywordSearchGlobalLanguageSettingsPanel.enableUTF16Checkbox.text=UTF16LE\u304a\u3088\u3073UTF16BE\u6587\u5b57\u5217\u62bd\u51fa\u3092\u6709\u52b9\u5316 KeywordSearchGlobalLanguageSettingsPanel.enableUTF16Checkbox.text=UTF16LE\u304a\u3088\u3073UTF16BE\u6587\u5b57\u5217\u62bd\u51fa\u3092\u6709\u52b9\u5316
KeywordSearchGlobalLanguageSettingsPanel.enableUTF8Checkbox.text=UTF8\u30c6\u30ad\u30b9\u30c8\u62bd\u51fa\u3092\u6709\u52b9\u5316\u3059\u308b KeywordSearchGlobalLanguageSettingsPanel.enableUTF8Checkbox.text=UTF8\u30c6\u30ad\u30b9\u30c8\u62bd\u51fa\u3092\u6709\u52b9\u5316\u3059\u308b
KeywordSearchGlobalLanguageSettingsPanel.ingestSettingsLabel.text=\u672a\u77e5\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u304b\u3089\u306e\u6587\u5b57\u5217\u62bd\u51fa\u306e\u305f\u3081\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u8a2d\u5b9a(\u5909\u66f4\u306f\u6b21\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3067\u6709\u52b9\u306b\u306a\u308a\u307e\u3059)\: KeywordSearchGlobalLanguageSettingsPanel.ingestSettingsLabel.text=\u672a\u77e5\u306e\u30d5\u30a1\u30a4\u30eb\u30bf\u30a4\u30d7\u304b\u3089\u306e\u6587\u5b57\u5217\u62bd\u51fa\u306e\u305f\u3081\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u8a2d\u5b9a(\u5909\u66f4\u306f\u6b21\u306e\u30a4\u30f3\u30b8\u30a7\u30b9\u30c8\u3067\u6709\u52b9\u306b\u306a\u308a\u307e\u3059)\:

View File

@ -16,32 +16,30 @@
<Layout> <Layout>
<DimensionLayout dim="0"> <DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/> <Component id="langPanel" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Component id="ingestSettingsLabel" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="ingestWarningLabel" pref="360" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Component id="languagesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="langPanel" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" min="-2" max="-2" attributes="0"/>
<Component id="ingestWarningLabel" pref="360" max="32767" attributes="0"/>
</Group>
</Group>
</Group> </Group>
<Group type="102" alignment="0" attributes="0"> <Group type="102" attributes="0">
<EmptySpace min="-2" pref="26" max="-2" attributes="0"/> <Group type="103" groupAlignment="0" attributes="0">
<Group type="103" groupAlignment="0" max="-2" attributes="0"> <Component id="languagesLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="enableUTF16Checkbox" min="-2" max="-2" attributes="0"/> <Group type="102" alignment="0" attributes="0">
<Component id="enableUTF8Checkbox" alignment="0" min="-2" max="-2" attributes="0"/> <EmptySpace min="-2" pref="16" max="-2" attributes="0"/>
<Component id="enableOcrCheckbox" alignment="0" min="-2" max="-2" attributes="0"/> <Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="enableUTF16Checkbox" min="-2" max="-2" attributes="0"/>
<Component id="enableUTF8Checkbox" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Component id="ingestSettingsLabel" alignment="0" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
<EmptySpace min="-2" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -50,18 +48,16 @@
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="ingestSettingsLabel" min="-2" max="-2" attributes="0"/> <Component id="ingestSettingsLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Component id="enableOcrCheckbox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="enableUTF16Checkbox" min="-2" max="-2" attributes="0"/> <Component id="enableUTF16Checkbox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="enableUTF8Checkbox" min="-2" max="-2" attributes="0"/> <Component id="enableUTF8Checkbox" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="languagesLabel" min="-2" max="-2" attributes="0"/> <Component id="languagesLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="langPanel" pref="380" max="32767" attributes="0"/> <Component id="langPanel" pref="408" max="32767" attributes="0"/>
</Group> </Group>
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/> <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
@ -105,7 +101,7 @@
</DimensionLayout> </DimensionLayout>
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="378" max="32767" attributes="0"/> <EmptySpace min="0" pref="406" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
@ -139,16 +135,6 @@
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JCheckBox" name="enableOcrCheckbox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchGlobalLanguageSettingsPanel.enableOcrCheckbox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="enableOcrCheckboxActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="ingestWarningLabel"> <Component class="javax.swing.JLabel" name="ingestWarningLabel">
<Properties> <Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor"> <Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">

View File

@ -70,12 +70,6 @@ class KeywordSearchGlobalLanguageSettingsPanel extends javax.swing.JPanel implem
initScriptsCheckBoxes(); initScriptsCheckBoxes();
reloadScriptsCheckBoxes(); reloadScriptsCheckBoxes();
if (!PlatformUtil.isWindowsOS() || !PlatformUtil.is64BitOS()) {
enableOcrCheckbox.setText("Enable Optical Character Recognition (OCR) (Requires Windows 64-bit)");
enableOcrCheckbox.setSelected(false);
enableOcrCheckbox.setEnabled(false);
}
//allow panel to toggle its enabled status while it is open based on ingest events //allow panel to toggle its enabled status while it is open based on ingest events
IngestManager.getInstance().addIngestJobEventListener(new PropertyChangeListener() { IngestManager.getInstance().addIngestJobEventListener(new PropertyChangeListener() {
@ -136,9 +130,6 @@ class KeywordSearchGlobalLanguageSettingsPanel extends javax.swing.JPanel implem
= Boolean.parseBoolean(KeywordSearchSettings.getStringExtractOption(StringsExtractOptions.EXTRACT_UTF8.toString())); = Boolean.parseBoolean(KeywordSearchSettings.getStringExtractOption(StringsExtractOptions.EXTRACT_UTF8.toString()));
enableUTF8Checkbox.setSelected(utf8); enableUTF8Checkbox.setSelected(utf8);
boolean ocr = KeywordSearchSettings.getOcrOption();
enableOcrCheckbox.setSelected(ocr);
final List<SCRIPT> serviceScripts = KeywordSearchSettings.getStringExtractScripts(); final List<SCRIPT> serviceScripts = KeywordSearchSettings.getStringExtractScripts();
final int components = checkPanel.getComponentCount(); final int components = checkPanel.getComponentCount();
@ -170,7 +161,6 @@ class KeywordSearchGlobalLanguageSettingsPanel extends javax.swing.JPanel implem
ingestWarningLabel.setVisible(ingestRunning); ingestWarningLabel.setVisible(ingestRunning);
enableUTF16Checkbox.setEnabled(!ingestRunning); enableUTF16Checkbox.setEnabled(!ingestRunning);
enableUTF8Checkbox.setEnabled(!ingestRunning); enableUTF8Checkbox.setEnabled(!ingestRunning);
enableOcrCheckbox.setEnabled(!ingestRunning);
} }
/** /**
@ -188,7 +178,6 @@ class KeywordSearchGlobalLanguageSettingsPanel extends javax.swing.JPanel implem
enableUTF8Checkbox = new javax.swing.JCheckBox(); enableUTF8Checkbox = new javax.swing.JCheckBox();
enableUTF16Checkbox = new javax.swing.JCheckBox(); enableUTF16Checkbox = new javax.swing.JCheckBox();
ingestSettingsLabel = new javax.swing.JLabel(); ingestSettingsLabel = new javax.swing.JLabel();
enableOcrCheckbox = new javax.swing.JCheckBox();
ingestWarningLabel = new javax.swing.JLabel(); ingestWarningLabel = new javax.swing.JLabel();
org.openide.awt.Mnemonics.setLocalizedText(languagesLabel, org.openide.util.NbBundle.getMessage(KeywordSearchGlobalLanguageSettingsPanel.class, "KeywordSearchGlobalLanguageSettingsPanel.languagesLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(languagesLabel, org.openide.util.NbBundle.getMessage(KeywordSearchGlobalLanguageSettingsPanel.class, "KeywordSearchGlobalLanguageSettingsPanel.languagesLabel.text")); // NOI18N
@ -205,7 +194,7 @@ class KeywordSearchGlobalLanguageSettingsPanel extends javax.swing.JPanel implem
); );
checkPanelLayout.setVerticalGroup( checkPanelLayout.setVerticalGroup(
checkPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) checkPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 378, Short.MAX_VALUE) .addGap(0, 406, Short.MAX_VALUE)
); );
langPanel.setViewportView(checkPanel); langPanel.setViewportView(checkPanel);
@ -226,13 +215,6 @@ class KeywordSearchGlobalLanguageSettingsPanel extends javax.swing.JPanel implem
org.openide.awt.Mnemonics.setLocalizedText(ingestSettingsLabel, org.openide.util.NbBundle.getMessage(KeywordSearchGlobalLanguageSettingsPanel.class, "KeywordSearchGlobalLanguageSettingsPanel.ingestSettingsLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(ingestSettingsLabel, org.openide.util.NbBundle.getMessage(KeywordSearchGlobalLanguageSettingsPanel.class, "KeywordSearchGlobalLanguageSettingsPanel.ingestSettingsLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(enableOcrCheckbox, org.openide.util.NbBundle.getMessage(KeywordSearchGlobalLanguageSettingsPanel.class, "KeywordSearchGlobalLanguageSettingsPanel.enableOcrCheckbox.text")); // NOI18N
enableOcrCheckbox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
enableOcrCheckboxActionPerformed(evt);
}
});
ingestWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/modules/hashdatabase/warning16.png"))); // NOI18N ingestWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/modules/hashdatabase/warning16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(ingestWarningLabel, org.openide.util.NbBundle.getMessage(KeywordSearchGlobalLanguageSettingsPanel.class, "KeywordSearchGlobalLanguageSettingsPanel.ingestWarningLabel.text")); // NOI18N org.openide.awt.Mnemonics.setLocalizedText(ingestWarningLabel, org.openide.util.NbBundle.getMessage(KeywordSearchGlobalLanguageSettingsPanel.class, "KeywordSearchGlobalLanguageSettingsPanel.ingestWarningLabel.text")); // NOI18N
@ -241,23 +223,22 @@ class KeywordSearchGlobalLanguageSettingsPanel extends javax.swing.JPanel implem
layout.setHorizontalGroup( layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addComponent(langPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(ingestSettingsLabel) .addComponent(ingestWarningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 360, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(languagesLabel, javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(langPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(ingestWarningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 360, Short.MAX_VALUE))))
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(26, 26, 26) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(languagesLabel)
.addComponent(enableUTF16Checkbox) .addGroup(layout.createSequentialGroup()
.addComponent(enableUTF8Checkbox) .addGap(16, 16, 16)
.addComponent(enableOcrCheckbox)))) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(enableUTF16Checkbox)
.addComponent(enableUTF8Checkbox)))
.addComponent(ingestSettingsLabel))
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap()) .addContainerGap())
); );
layout.setVerticalGroup( layout.setVerticalGroup(
@ -265,18 +246,16 @@ class KeywordSearchGlobalLanguageSettingsPanel extends javax.swing.JPanel implem
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addComponent(ingestSettingsLabel) .addComponent(ingestSettingsLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(enableOcrCheckbox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(enableUTF16Checkbox) .addComponent(enableUTF16Checkbox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(enableUTF8Checkbox) .addComponent(enableUTF8Checkbox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(languagesLabel) .addComponent(languagesLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(langPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)) .addComponent(langPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 408, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE) .addGap(0, 0, Short.MAX_VALUE)
.addComponent(ingestWarningLabel))) .addComponent(ingestWarningLabel)))
@ -301,13 +280,8 @@ class KeywordSearchGlobalLanguageSettingsPanel extends javax.swing.JPanel implem
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_enableUTF16CheckboxActionPerformed }//GEN-LAST:event_enableUTF16CheckboxActionPerformed
private void enableOcrCheckboxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_enableOcrCheckboxActionPerformed
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_enableOcrCheckboxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JPanel checkPanel; private javax.swing.JPanel checkPanel;
private javax.swing.JCheckBox enableOcrCheckbox;
private javax.swing.JCheckBox enableUTF16Checkbox; private javax.swing.JCheckBox enableUTF16Checkbox;
private javax.swing.JCheckBox enableUTF8Checkbox; private javax.swing.JCheckBox enableUTF8Checkbox;
private javax.swing.JLabel ingestSettingsLabel; private javax.swing.JLabel ingestSettingsLabel;
@ -322,7 +296,6 @@ class KeywordSearchGlobalLanguageSettingsPanel extends javax.swing.JPanel implem
Boolean.toString(enableUTF8Checkbox.isSelected())); Boolean.toString(enableUTF8Checkbox.isSelected()));
KeywordSearchSettings.setStringExtractOption(StringsExtractOptions.EXTRACT_UTF16.toString(), KeywordSearchSettings.setStringExtractOption(StringsExtractOptions.EXTRACT_UTF16.toString(),
Boolean.toString(enableUTF16Checkbox.isSelected())); Boolean.toString(enableUTF16Checkbox.isSelected()));
KeywordSearchSettings.setOcrOption(enableOcrCheckbox.isSelected());
if (toUpdate != null) { if (toUpdate != null) {
KeywordSearchSettings.setStringExtractScripts(toUpdate); KeywordSearchSettings.setStringExtractScripts(toUpdate);

View File

@ -23,6 +23,7 @@
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="ingestWarningLabel" alignment="0" max="32767" attributes="0"/>
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0"> <Group type="102" alignment="0" attributes="0">
@ -30,17 +31,23 @@
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="settingsSeparator" min="-2" pref="326" max="-2" attributes="0"/> <Component id="settingsSeparator" min="-2" pref="326" max="-2" attributes="0"/>
</Group> </Group>
<Group type="102" alignment="0" attributes="0">
<Component id="informationLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="informationSeparator" min="-2" pref="309" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0"> <Group type="102" attributes="0">
<EmptySpace min="10" pref="10" max="-2" attributes="0"/> <EmptySpace min="10" pref="10" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Component id="skipNSRLCheckBox" min="-2" max="-2" attributes="0"/> <Component id="skipNSRLCheckBox" min="-2" max="-2" attributes="0"/>
<Component id="showSnippetsCB" alignment="0" min="-2" max="-2" attributes="0"/> <Component id="showSnippetsCB" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0"> <Component id="ocrCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="informationLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="informationSeparator" min="-2" pref="309" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="10" pref="10" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="filesIndexedLabel" linkSize="1" min="-2" max="-2" attributes="0"/> <Component id="filesIndexedLabel" linkSize="1" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/> <EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="filesIndexedValue" min="-2" max="-2" attributes="0"/> <Component id="filesIndexedValue" min="-2" max="-2" attributes="0"/>
@ -66,7 +73,6 @@
</Group> </Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/> <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group> </Group>
<Component id="ingestWarningLabel" alignment="0" max="32767" attributes="0"/>
</Group> </Group>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
</Group> </Group>
@ -85,6 +91,8 @@
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="showSnippetsCB" min="-2" max="-2" attributes="0"/> <Component id="showSnippetsCB" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="ocrCheckBox" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="frequencyLabel" min="-2" max="-2" attributes="0"/> <Component id="frequencyLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="timeRadioButton1" min="-2" max="-2" attributes="0"/> <Component id="timeRadioButton1" min="-2" max="-2" attributes="0"/>
@ -113,7 +121,7 @@
</Group> </Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/> <EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="ingestWarningLabel" min="-2" max="-2" attributes="0"/> <Component id="ingestWarningLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="66" max="32767" attributes="0"/> <EmptySpace pref="43" max="32767" attributes="0"/>
</Group> </Group>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
@ -270,5 +278,15 @@
</Property> </Property>
</Properties> </Properties>
</Component> </Component>
<Component class="javax.swing.JCheckBox" name="ocrCheckBox">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/keywordsearch/Bundle.properties" key="KeywordSearchGlobalSearchSettingsPanel.ocrCheckBox.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="ocrCheckBoxActionPerformed"/>
</Events>
</Component>
</SubComponents> </SubComponents>
</Form> </Form>

View File

@ -23,8 +23,10 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.logging.Level; import java.util.logging.Level;
import org.netbeans.spi.options.OptionsPanelController; import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel; import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.keywordsearch.KeywordSearchIngestModule.UpdateFrequency; import org.sleuthkit.autopsy.keywordsearch.KeywordSearchIngestModule.UpdateFrequency;
@ -47,9 +49,11 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
private void activateWidgets() { private void activateWidgets() {
skipNSRLCheckBox.setSelected(KeywordSearchSettings.getSkipKnown()); skipNSRLCheckBox.setSelected(KeywordSearchSettings.getSkipKnown());
showSnippetsCB.setSelected(KeywordSearchSettings.getShowSnippets()); showSnippetsCB.setSelected(KeywordSearchSettings.getShowSnippets());
ocrCheckBox.setSelected(KeywordSearchSettings.getOcrOption());
boolean ingestRunning = IngestManager.getInstance().isIngestRunning(); boolean ingestRunning = IngestManager.getInstance().isIngestRunning();
ingestWarningLabel.setVisible(ingestRunning); ingestWarningLabel.setVisible(ingestRunning);
skipNSRLCheckBox.setEnabled(!ingestRunning); skipNSRLCheckBox.setEnabled(!ingestRunning);
ocrCheckBox.setEnabled(!ingestRunning);
setTimeSettingEnabled(!ingestRunning); setTimeSettingEnabled(!ingestRunning);
final UpdateFrequency curFreq = KeywordSearchSettings.getUpdateFrequency(); final UpdateFrequency curFreq = KeywordSearchSettings.getUpdateFrequency();
@ -104,6 +108,7 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
showSnippetsCB = new javax.swing.JCheckBox(); showSnippetsCB = new javax.swing.JCheckBox();
timeRadioButton5 = new javax.swing.JRadioButton(); timeRadioButton5 = new javax.swing.JRadioButton();
ingestWarningLabel = new javax.swing.JLabel(); ingestWarningLabel = new javax.swing.JLabel();
ocrCheckBox = new javax.swing.JCheckBox();
skipNSRLCheckBox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.skipNSRLCheckBox.text")); // NOI18N skipNSRLCheckBox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.skipNSRLCheckBox.text")); // NOI18N
skipNSRLCheckBox.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.skipNSRLCheckBox.toolTipText")); // NOI18N skipNSRLCheckBox.setToolTipText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.skipNSRLCheckBox.toolTipText")); // NOI18N
@ -177,6 +182,13 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
ingestWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/modules/hashdatabase/warning16.png"))); // NOI18N ingestWarningLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/modules/hashdatabase/warning16.png"))); // NOI18N
ingestWarningLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.ingestWarningLabel.text")); // NOI18N ingestWarningLabel.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.ingestWarningLabel.text")); // NOI18N
ocrCheckBox.setText(org.openide.util.NbBundle.getMessage(KeywordSearchGlobalSearchSettingsPanel.class, "KeywordSearchGlobalSearchSettingsPanel.ocrCheckBox.text")); // NOI18N
ocrCheckBox.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
ocrCheckBoxActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout); this.setLayout(layout);
layout.setHorizontalGroup( layout.setHorizontalGroup(
@ -184,12 +196,19 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addContainerGap() .addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(ingestWarningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(settingsLabel) .addComponent(settingsLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(settingsSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 326, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(settingsSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 326, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createSequentialGroup()
.addGap(10, 10, 10)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(skipNSRLCheckBox)
.addComponent(showSnippetsCB)
.addComponent(ocrCheckBox)))
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(informationLabel) .addComponent(informationLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@ -197,8 +216,6 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addGap(10, 10, 10) .addGap(10, 10, 10)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(skipNSRLCheckBox)
.addComponent(showSnippetsCB)
.addGroup(layout.createSequentialGroup() .addGroup(layout.createSequentialGroup()
.addComponent(filesIndexedLabel) .addComponent(filesIndexedLabel)
.addGap(18, 18, 18) .addGap(18, 18, 18)
@ -216,8 +233,7 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
.addComponent(chunksLabel) .addComponent(chunksLabel)
.addGap(18, 18, 18) .addGap(18, 18, 18)
.addComponent(chunksValLabel))))) .addComponent(chunksValLabel)))))
.addGap(0, 0, Short.MAX_VALUE)) .addGap(0, 0, Short.MAX_VALUE)))
.addComponent(ingestWarningLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap()) .addContainerGap())
); );
@ -235,6 +251,8 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(showSnippetsCB) .addComponent(showSnippetsCB)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(ocrCheckBox)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(frequencyLabel) .addComponent(frequencyLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(timeRadioButton1) .addComponent(timeRadioButton1)
@ -260,7 +278,7 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
.addComponent(chunksValLabel)) .addComponent(chunksValLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(ingestWarningLabel) .addComponent(ingestWarningLabel)
.addContainerGap(66, Short.MAX_VALUE)) .addContainerGap(43, Short.MAX_VALUE))
); );
}// </editor-fold>//GEN-END:initComponents }// </editor-fold>//GEN-END:initComponents
@ -292,6 +310,10 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null); firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_timeRadioButton4ActionPerformed }//GEN-LAST:event_timeRadioButton4ActionPerformed
private void ocrCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ocrCheckBoxActionPerformed
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_ocrCheckBoxActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables // Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JLabel chunksLabel; private javax.swing.JLabel chunksLabel;
private javax.swing.JLabel chunksValLabel; private javax.swing.JLabel chunksValLabel;
@ -301,6 +323,7 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
private javax.swing.JLabel informationLabel; private javax.swing.JLabel informationLabel;
private javax.swing.JSeparator informationSeparator; private javax.swing.JSeparator informationSeparator;
private javax.swing.JLabel ingestWarningLabel; private javax.swing.JLabel ingestWarningLabel;
private javax.swing.JCheckBox ocrCheckBox;
private javax.swing.JLabel settingsLabel; private javax.swing.JLabel settingsLabel;
private javax.swing.JSeparator settingsSeparator; private javax.swing.JSeparator settingsSeparator;
private javax.swing.JCheckBox showSnippetsCB; private javax.swing.JCheckBox showSnippetsCB;
@ -318,6 +341,7 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
KeywordSearchSettings.setSkipKnown(skipNSRLCheckBox.isSelected()); KeywordSearchSettings.setSkipKnown(skipNSRLCheckBox.isSelected());
KeywordSearchSettings.setUpdateFrequency(getSelectedTimeValue()); KeywordSearchSettings.setUpdateFrequency(getSelectedTimeValue());
KeywordSearchSettings.setShowSnippets(showSnippetsCB.isSelected()); KeywordSearchSettings.setShowSnippets(showSnippetsCB.isSelected());
KeywordSearchSettings.setOcrOption(ocrCheckBox.isSelected());
} }
@Override @Override
@ -349,6 +373,7 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
return UpdateFrequency.DEFAULT; return UpdateFrequency.DEFAULT;
} }
@NbBundle.Messages({"KeywordSearchGlobalSearchSettingsPanel.customizeComponents.windowsOCR=Enable Optical Character Recognition (OCR) (Requires Windows 64-bit)"})
private void customizeComponents() { private void customizeComponents() {
timeGroup.add(timeRadioButton1); timeGroup.add(timeRadioButton1);
@ -365,6 +390,12 @@ class KeywordSearchGlobalSearchSettingsPanel extends javax.swing.JPanel implemen
} catch (KeywordSearchModuleException | NoOpenCoreException ex) { } catch (KeywordSearchModuleException | NoOpenCoreException ex) {
logger.log(Level.WARNING, "Could not get number of indexed files/chunks"); //NON-NLS logger.log(Level.WARNING, "Could not get number of indexed files/chunks"); //NON-NLS
} }
if (!PlatformUtil.isWindowsOS() || !PlatformUtil.is64BitOS()) {
ocrCheckBox.setText(Bundle.KeywordSearchGlobalSearchSettingsPanel_customizeComponents_windowsOCR());
ocrCheckBox.setSelected(false);
ocrCheckBox.setEnabled(false);
}
KeywordSearch.addNumIndexedFilesChangeListener( KeywordSearch.addNumIndexedFilesChangeListener(
new PropertyChangeListener() { new PropertyChangeListener() {

View File

@ -88,7 +88,7 @@ ExtractZone_progress_Msg=Extracting :Zone.Identifer files
ExtractZone_Restricted=Restricted Sites Zone ExtractZone_Restricted=Restricted Sites Zone
ExtractZone_Trusted=Trusted Sites Zone ExtractZone_Trusted=Trusted Sites Zone
OpenIDE-Module-Display-Category=Ingest Module OpenIDE-Module-Display-Category=Ingest Module
OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\n\The module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web activity (sites visited, stored cookies, book marked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\nThe module currently supports Windows only disk images.\nThe plugin is also fully functional when deployed on Windows version of Autopsy. OpenIDE-Module-Long-Description=Recent Activity ingest module.\n\nThe module extracts useful information about the recent user activity on the disk image being ingested, such as:\n\n- Recently open documents,\n- Web activity (sites visited, stored cookies, book marked sites, search engine queries, file downloads),\n- Recently attached devices,\n- Installed programs.\n\nThe module currently supports Windows only disk images.\nThe plugin is also fully functional when deployed on Windows version of Autopsy.
OpenIDE-Module-Name=RecentActivity OpenIDE-Module-Name=RecentActivity
OpenIDE-Module-Short-Description=Recent Activity finder ingest module OpenIDE-Module-Short-Description=Recent Activity finder ingest module
Chrome.moduleName=Chromium Chrome.moduleName=Chromium

View File

@ -474,7 +474,7 @@ class Chromium extends Extract {
} }
List<HashMap<String, Object>> tempList = this.dbConnect(temps, COOKIE_QUERY); List<HashMap<String, Object>> tempList = this.dbConnect(temps, COOKIE_QUERY);
logger.log(Level.INFO, "{0}- Now getting cookies from {1} with {2}artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS logger.log(Level.INFO, "{0}- Now getting cookies from {1} with {2} artifacts identified.", new Object[]{moduleName, temps, tempList.size()}); //NON-NLS
for (HashMap<String, Object> result : tempList) { for (HashMap<String, Object> result : tempList) {
Collection<BlackboardAttribute> bbattributes = new ArrayList<>(); Collection<BlackboardAttribute> bbattributes = new ArrayList<>();
bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL, bbattributes.add(new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_URL,

View File

@ -1784,7 +1784,8 @@ class ExtractRegistry extends Extract {
line = line.trim(); line = line.trim();
usedTime = Long.valueOf(0); usedTime = Long.valueOf(0);
if (!line.contains("**") && !line.contains("----------") && !line.contains("LastWrite") if (!line.contains("**") && !line.contains("----------") && !line.contains("LastWrite")
&& !line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.contains("TrustRecords")) { && !line.contains(SECTION_DIVIDER) && !line.isEmpty() && !line.contains("TrustRecords")
&& !line.contains("VBAWarnings =")) {
// Columns are // Columns are
// Date : <File Name>/<Website> // Date : <File Name>/<Website>
// Split line on " : " which is the record delimiter between position and file // Split line on " : " which is the record delimiter between position and file

View File

@ -116,7 +116,7 @@ final class ExtractZoneIdentifier extends Extract {
/** /**
* Process a single Zone Identifier file. * Process a single Zone Identifier file.
* *
* @param context IngetJobContext * @param context IngestJobContext
* @param dataSource Content * @param dataSource Content
* @param zoneFile Zone Indentifier file * @param zoneFile Zone Indentifier file
* @param associatedObjectArtifacts List for TSK_ASSOCIATED_OBJECT artifacts * @param associatedObjectArtifacts List for TSK_ASSOCIATED_OBJECT artifacts
@ -149,7 +149,7 @@ final class ExtractZoneIdentifier extends Extract {
if (!knownPathIDs.contains(downloadFile.getDataSourceObjectId())) { if (!knownPathIDs.contains(downloadFile.getDataSourceObjectId())) {
// The zone identifier file is the parent of this artifact // The zone identifier file is the parent of this artifact
// because it is the file we parsed to get the data // because it is the file we parsed to get the data
BlackboardArtifact downloadBba = createDownloadArtifact(zoneFile, zoneInfo); BlackboardArtifact downloadBba = createDownloadArtifact(zoneFile, zoneInfo, downloadFile);
if (downloadBba != null) { if (downloadBba != null) {
downloadArtifacts.add(downloadBba); downloadArtifacts.add(downloadBba);
// create a TSK_ASSOCIATED_OBJECT for the downloaded file, associating it with the TSK_WEB_DOWNLOAD artifact. // create a TSK_ASSOCIATED_OBJECT for the downloaded file, associating it with the TSK_WEB_DOWNLOAD artifact.
@ -227,16 +227,24 @@ final class ExtractZoneIdentifier extends Extract {
* *
* @param zoneFile Zone identifier file * @param zoneFile Zone identifier file
* @param zoneInfo ZoneIdentifierInfo file wrapper object * @param zoneInfo ZoneIdentifierInfo file wrapper object
* @param downloadFile The file associated with the zone identifier
* *
* @return BlackboardArifact for the given parameters * @return BlackboardArifact for the given parameters
*/ */
private BlackboardArtifact createDownloadArtifact(AbstractFile zoneFile, ZoneIdentifierInfo zoneInfo) { private BlackboardArtifact createDownloadArtifact(AbstractFile zoneFile, ZoneIdentifierInfo zoneInfo, AbstractFile downloadFile) {
String downloadFilePath = downloadFile.getParentPath() + downloadFile.getName();
Collection<BlackboardAttribute> bbattributes = createDownloadAttributes( Collection<BlackboardAttribute> bbattributes = createDownloadAttributes(
null, null, downloadFilePath, null,
zoneInfo.getURL(), null, zoneInfo.getURL(), null,
(zoneInfo.getURL() != null ? NetworkUtils.extractDomain(zoneInfo.getURL()) : ""), (zoneInfo.getURL() != null ? NetworkUtils.extractDomain(zoneInfo.getURL()) : ""),
null); null);
if (zoneInfo.getZoneIdAsString() != null) {
bbattributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT,
RecentActivityExtracterModuleFactory.getModuleName(),
zoneInfo.getZoneIdAsString()));
}
return createArtifactWithAttributes(TSK_WEB_DOWNLOAD, zoneFile, bbattributes); return createArtifactWithAttributes(TSK_WEB_DOWNLOAD, zoneFile, bbattributes);
} }

View File

@ -156,7 +156,7 @@
</copy> </copy>
<property name="app.property.file" value="${zip-tmp}/${app.name}/etc/${app.name}.conf" /> <property name="app.property.file" value="${zip-tmp}/${app.name}/etc/${app.name}.conf" />
<var name="jvm-value" value="--branding ${app.name} -J-Xms24m -J-Xmx4G -J-Xverify:none -J-XX:+UseG1GC -J-XX:+UseStringDeduplication"/> <var name="jvm-value" value="--branding ${app.name} -J-Xms24m -J-Xmx4G -J-Xverify:none -J-XX:+UseG1GC -J-XX:+UseStringDeduplication -J-Dprism.order=sw"/>
<!-- for Japanese localized version add option: -Duser.language=ja --> <!-- for Japanese localized version add option: -Duser.language=ja -->