diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties index f38bcbc815..0a415c8ca8 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/Bundle.properties @@ -38,8 +38,6 @@ FilesSetRulePanel.interesting.jLabel5.text=Enter information about files that yo FilesSetRulePanel.ingest.jLabel5.text=Enter information about files that you want to run ingest on. FilesSetRulePanel.nameCheck.text=Name Pattern: FilesSetRulePanel.pathCheck.text=Path Pattern: -FilesSetRulePanel.mimeCheck.text=MIME Type: -FilesSetRulePanel.fileSizeCheck.text=File Size: FilesSetRulePanel.filesRadioButton.text=Files FilesSetRulePanel.dirsRadioButton.text=Directories FilesSetDefsPanel.interesting.setsListLabel.text=Rule Sets: @@ -79,3 +77,10 @@ FilesSetDefsPanel.ingoreUnallocCheckbox.text=Ignore Unallocated Space FilesSetDefsPanel.ingoreUnallocCheckbox.toolTipText=Ignores unallocated space, such as deleted files. May run faster but produce less complete results. FilesSetDefsPanel.ingestWarningLabel.text=Ingest is ongoing, some settings will be unavailable until it finishes. FilesSetDefsPanel.allRadioButton.text=All +FilesSetRulePanel.dateCheck.text=Modified Within: +FilesSetRulePanel.daysAgoLabel.text=day(s) +FilesSetRulePanel.fileSizeCheck.text=File Size: +FilesSetRulePanel.mimeCheck.text=MIME Type: +FilesSetDefsPanel.daysAgoTextField.text= +FilesSetDefsPanel.modifiedDateLabel.text=Modified Within: +FilesSetDefsPanel.daysAgoLabel.text=day(s) diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSet.java b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSet.java index 38d7285fc1..913db37528 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSet.java +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSet.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -25,6 +25,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; import java.util.regex.Pattern; +import org.openide.util.NbBundle; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.TskData; @@ -169,6 +170,7 @@ public final class FilesSet implements Serializable { private final ParentPathCondition pathCondition; private final MimeTypeCondition mimeTypeCondition; private final FileSizeCondition fileSizeCondition; + private final DateCondition dateCondition; private final List conditions = new ArrayList<>(); /** @@ -180,8 +182,10 @@ public final class FilesSet implements Serializable { * @param pathCondition A file path condition, may be null. * @param mimeTypeCondition A file mime type condition, may be null. * @param fileSizeCondition A file size condition, may be null. + * @param dateCondition A file date created or modified condition, + * may be null */ - Rule(String ruleName, FileNameCondition fileNameCondition, MetaTypeCondition metaTypeCondition, ParentPathCondition pathCondition, MimeTypeCondition mimeTypeCondition, FileSizeCondition fileSizeCondition) { + Rule(String ruleName, FileNameCondition fileNameCondition, MetaTypeCondition metaTypeCondition, ParentPathCondition pathCondition, MimeTypeCondition mimeTypeCondition, FileSizeCondition fileSizeCondition, DateCondition dateCondition) { // since ruleName is optional, ruleUUID can be used to uniquely identify a rule. this.uuid = UUID.randomUUID().toString(); if (metaTypeCondition == null) { @@ -216,6 +220,10 @@ public final class FilesSet implements Serializable { if (this.pathCondition != null) { this.conditions.add(this.pathCondition); } + this.dateCondition = dateCondition; + if (this.dateCondition != null) { + this.conditions.add(this.dateCondition); + } } /** @@ -254,6 +262,10 @@ public final class FilesSet implements Serializable { return this.pathCondition; } + DateCondition getDateCondition() { + return this.dateCondition; + } + /** * Determines whether or not a file satisfies the rule. * @@ -270,6 +282,10 @@ public final class FilesSet implements Serializable { return true; } + @NbBundle.Messages({ + "# {0} - daysAgo", + "FilesSet.rule.dateRule.toString=(modified within {0} day(s))" + }) @Override public String toString() { // This override is designed to provide a display name for use with @@ -283,6 +299,8 @@ public final class FilesSet implements Serializable { } else if (this.fileSizeCondition != null) { return this.ruleName + " (" + fileSizeCondition.getComparator().getSymbol() + " " + fileSizeCondition.getSizeValue() + " " + fileSizeCondition.getUnit().getName() + ")"; + } else if (this.dateCondition != null) { + return this.ruleName + Bundle.FilesSet_rule_dateRule_toString(dateCondition.getDaysAgo()); } else { return this.ruleName + " ()"; } @@ -537,7 +555,7 @@ public final class FilesSet implements Serializable { case FILES: return file.isFile(); case DIRECTORIES: - return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR + return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_DIR || file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_VIRT_DIR; case FILES_AND_DIRECTORIES: return file.getMetaType() == TskData.TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG @@ -737,6 +755,46 @@ public final class FilesSet implements Serializable { } + /** + * A class for checking whether a file's creation or modification + * occured in a specific range of time + */ + static final class DateCondition implements FileAttributeCondition { + + private final static long DAY_IN_S = 60 * 60 * 24; + + private int daysAgo; + + /** + * Construct a new DateCondition + * + * @param days - files created or modified more recently than this + * number of days will pass + */ + DateCondition(int days) { + daysAgo = days; + } + + /** + * Get the number of days which this condition allows to pass + * + * @return integer value of the number days which will pass + */ + int getDaysAgo() { + return daysAgo; + } + + @Override + public boolean passes(AbstractFile file) { + long dateThreshold = System.currentTimeMillis() / 1000 - daysAgo * DAY_IN_S; + if (file.getCrtime() > dateThreshold || file.getMtime() > dateThreshold) { + return true; + } + return false; + } + + } + /** * A file name extension condition for an interesting files set * membership rule. The immutability of a file name extension condition diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetDefsPanel.form b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetDefsPanel.form index bffb00f33b..02d4cec624 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetDefsPanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetDefsPanel.form @@ -90,11 +90,69 @@ + - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -102,97 +160,22 @@ - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -213,8 +196,8 @@ - - + + @@ -223,7 +206,7 @@ - + @@ -232,14 +215,14 @@ - + - + @@ -250,26 +233,32 @@ - + - + - + - + - + + + + + + + @@ -996,6 +985,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetDefsPanel.java b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetDefsPanel.java index c67051be97..4afdf6d91e 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetDefsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetDefsPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -251,6 +251,7 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp this.fileNameRegexCheckbox.setSelected(false); this.filesRadioButton.setSelected(true); this.rulePathConditionTextField.setText(""); + this.daysAgoTextField.setText(""); this.rulePathConditionRegexCheckBox.setSelected(false); this.mimeTypeComboBox.setSelectedIndex(0); this.equalitySignComboBox.setSelectedIndex(2); @@ -326,7 +327,7 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp FilesSet.Rule.ParentPathCondition pathCondition = rule.getPathCondition(); FilesSet.Rule.MimeTypeCondition mimeTypeCondition = rule.getMimeTypeCondition(); FilesSet.Rule.FileSizeCondition fileSizeCondition = rule.getFileSizeCondition(); - + FilesSet.Rule.DateCondition dateCondition = rule.getDateCondition(); // Populate the components that display the properties of the // selected rule. if (nameCondition != null) { @@ -372,7 +373,12 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp FilesSetDefsPanel.this.equalitySignComboBox.setSelectedIndex(2); FilesSetDefsPanel.this.fileSizeSpinner.setValue(0); } - + if (dateCondition != null){ + FilesSetDefsPanel.this.daysAgoTextField.setText(Integer.toString(dateCondition.getDaysAgo())); + } + else { + FilesSetDefsPanel.this.daysAgoTextField.setText(""); + } // Enable the new, edit and delete rule buttons. FilesSetDefsPanel.this.newRuleButton.setEnabled(true && canBeEnabled); FilesSetDefsPanel.this.editRuleButton.setEnabled(true && canBeEnabled); @@ -477,7 +483,7 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp if (selectedRule != null) { rules.remove(selectedRule.getUuid()); } - FilesSet.Rule newRule = new FilesSet.Rule(panel.getRuleName(), panel.getFileNameCondition(), panel.getMetaTypeCondition(), panel.getPathCondition(), panel.getMimeTypeCondition(), panel.getFileSizeCondition()); + FilesSet.Rule newRule = new FilesSet.Rule(panel.getRuleName(), panel.getFileNameCondition(), panel.getMetaTypeCondition(), panel.getPathCondition(), panel.getMimeTypeCondition(), panel.getFileSizeCondition(), panel.getDateCondition()); rules.put(newRule.getUuid(), newRule); // Add the new/edited files set definition, replacing any previous @@ -590,6 +596,9 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp copySetButton = new javax.swing.JButton(); importSetButton = new javax.swing.JButton(); exportSetButton = new javax.swing.JButton(); + modifiedDateLabel = new javax.swing.JLabel(); + daysAgoTextField = new javax.swing.JTextField(); + daysAgoLabel = new javax.swing.JLabel(); setFont(getFont().deriveFont(getFont().getStyle() & ~java.awt.Font.BOLD, 11)); @@ -841,6 +850,17 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp } }); + org.openide.awt.Mnemonics.setLocalizedText(modifiedDateLabel, org.openide.util.NbBundle.getMessage(FilesSetDefsPanel.class, "FilesSetDefsPanel.modifiedDateLabel.text")); // NOI18N + + daysAgoTextField.setEditable(false); + daysAgoTextField.setHorizontalAlignment(javax.swing.JTextField.TRAILING); + daysAgoTextField.setText(org.openide.util.NbBundle.getMessage(FilesSetDefsPanel.class, "FilesSetDefsPanel.daysAgoTextField.text")); // NOI18N + daysAgoTextField.setMinimumSize(new java.awt.Dimension(60, 20)); + daysAgoTextField.setPreferredSize(new java.awt.Dimension(60, 20)); + + org.openide.awt.Mnemonics.setLocalizedText(daysAgoLabel, org.openide.util.NbBundle.getMessage(FilesSetDefsPanel.class, "FilesSetDefsPanel.daysAgoLabel.text")); // NOI18N + daysAgoLabel.setEnabled(false); + javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( @@ -867,83 +887,75 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp .addComponent(setsListLabel)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(separator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(rulesListScrollPane, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(setDescScrollPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(101, 101, 101) + .addGap(16, 16, 16) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(jLabel7) + .addComponent(jLabel8) + .addComponent(jLabel2) + .addComponent(jLabel4) + .addComponent(modifiedDateLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(rulePathConditionTextField) + .addComponent(fileNameTextField, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(mimeTypeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(equalitySignComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(fileSizeSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(fileSizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(fileNameRadioButton) + .addComponent(rulePathConditionRegexCheckBox) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(daysAgoTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(daysAgoLabel))) + .addGap(0, 0, Short.MAX_VALUE))))) + .addGap(8, 8, 8)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(rulesListLabel) + .addGroup(jPanel1Layout.createSequentialGroup() + .addComponent(ignoreKnownFilesCheckbox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(ingoreUnallocCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel5) + .addComponent(jLabel6)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(ingestWarningLabel)) + .addGroup(jPanel1Layout.createSequentialGroup() + .addGap(95, 95, 95) .addComponent(filesRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(dirsRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(allRadioButton)) .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(105, 105, 105) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(fileNameRadioButton) - .addGap(4, 4, 4) - .addComponent(fileNameExtensionRadioButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(fileNameRegexCheckbox)) - .addComponent(rulePathConditionRegexCheckBox))) + .addGap(174, 174, 174) + .addComponent(fileNameExtensionRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(fileNameRegexCheckbox)) + .addComponent(jLabel1) .addGroup(jPanel1Layout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(rulesListLabel) - .addComponent(jLabel1) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(newRuleButton) - .addGap(18, 18, 18) - .addComponent(editRuleButton) - .addGap(18, 18, 18) - .addComponent(deleteRuleButton)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(ignoreKnownFilesCheckbox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(ingoreUnallocCheckbox, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel5) - .addComponent(jLabel6)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(ingestWarningLabel))))) - .addGap(24, 28, Short.MAX_VALUE)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGap(22, 22, 22) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel7) - .addComponent(jLabel8)) - .addGap(18, 18, 18)) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel3) - .addComponent(jLabel2)) - .addGap(6, 6, 6)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addComponent(jLabel4) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)))) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(equalitySignComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(fileSizeSpinner, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(fileSizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(rulePathConditionTextField) - .addComponent(fileNameTextField, javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(mimeTypeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(rulesListScrollPane, javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(setDescScrollPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) - .addGap(8, 8, 8)))) + .addComponent(newRuleButton) + .addGap(18, 18, 18) + .addComponent(editRuleButton) + .addGap(18, 18, 18) + .addComponent(deleteRuleButton))) + .addGap(24, 28, Short.MAX_VALUE)))) ); jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {copySetButton, deleteSetButton, editSetButton, exportSetButton, importSetButton, newSetButton}); @@ -963,7 +975,7 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp .addGap(1, 1, 1)) .addComponent(ingestWarningLabel, javax.swing.GroupLayout.Alignment.TRAILING)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(setDescScrollPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 45, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(setDescScrollPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 45, Short.MAX_VALUE) .addGap(6, 6, 6) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(ignoreKnownFilesCheckbox) @@ -971,7 +983,7 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(rulesListLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(rulesListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 82, Short.MAX_VALUE) + .addComponent(rulesListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(newRuleButton) @@ -979,13 +991,13 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp .addComponent(deleteRuleButton)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel1) - .addGap(8, 8, 8) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel2) .addComponent(filesRadioButton) .addComponent(dirsRadioButton) .addComponent(allRadioButton)) - .addGap(8, 8, 8) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel3) .addComponent(fileNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)) @@ -994,23 +1006,28 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp .addComponent(fileNameRadioButton) .addComponent(fileNameExtensionRadioButton) .addComponent(fileNameRegexCheckbox)) - .addGap(8, 8, 8) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel4) .addComponent(rulePathConditionTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(6, 6, 6) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(rulePathConditionRegexCheckBox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel7) .addComponent(mimeTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jLabel8) .addComponent(equalitySignComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(fileSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(fileSizeUnitComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(5, 5, 5)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(modifiedDateLabel) + .addComponent(daysAgoTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(daysAgoLabel)) + .addContainerGap()) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -1262,6 +1279,8 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JRadioButton allRadioButton; private javax.swing.JButton copySetButton; + private javax.swing.JLabel daysAgoLabel; + private javax.swing.JTextField daysAgoTextField; private javax.swing.JButton deleteRuleButton; private javax.swing.JButton deleteSetButton; private javax.swing.JRadioButton dirsRadioButton; @@ -1294,6 +1313,7 @@ public final class FilesSetDefsPanel extends IngestModuleGlobalSettingsPanel imp private javax.swing.JScrollPane jScrollPane2; private javax.swing.JTextArea jTextArea1; private javax.swing.JComboBox mimeTypeComboBox; + private javax.swing.JLabel modifiedDateLabel; private javax.swing.JButton newRuleButton; private javax.swing.JButton newSetButton; private javax.swing.JCheckBox rulePathConditionRegexCheckBox; diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetRulePanel.form b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetRulePanel.form index 4777c108b4..3d7513f6bc 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetRulePanel.form +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetRulePanel.form @@ -23,82 +23,80 @@ - - + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - - - - - - - - - + - + @@ -106,17 +104,22 @@ - - - - - - - - - - - + + + + + + + + + + + + + + + + @@ -134,7 +137,7 @@ - + @@ -146,7 +149,13 @@ - + + + + + + + @@ -170,9 +179,6 @@ - - - @@ -380,5 +386,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetRulePanel.java b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetRulePanel.java index d70a5474ee..cbca5fd600 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetRulePanel.java +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetRulePanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2014-2017 Basis Technology Corp. + * Copyright 2014-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +19,6 @@ package org.sleuthkit.autopsy.modules.interestingitems; import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; import java.util.List; import java.util.SortedSet; import java.util.logging.Level; @@ -50,6 +49,8 @@ final class FilesSetRulePanel extends javax.swing.JPanel { "FilesSetRulePanel.NoMimeTypeError=Please select a valid MIME type.", "FilesSetRulePanel.NoNameError=Name cannot be empty", "FilesSetRulePanel.NoPathError=Path cannot be empty", + "FilesSetRulePanel.DaysAgoEmptyError=Number of days ago cannot be empty.", + "FilesSetRulePanel.DaysAgoInvalidError=Number of days ago must be a positive integer.", "FilesSetRulePanel.ZeroFileSizeError=File size condition value must not be 0 (Unless = is selected)." }) @@ -82,6 +83,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel { } else { populateMimeTypesComboBox(); } + this.dateCheckActionPerformed(null); populateComponentsWithDefaultValues(); this.setButtons(okButton, cancelButton); } @@ -108,12 +110,14 @@ final class FilesSetRulePanel extends javax.swing.JPanel { populateMimeTypesComboBox(); populateMimeConditionComponents(rule); populateSizeConditionComponents(rule); + } populateMimeTypesComboBox(); populateRuleNameComponent(rule); populateTypeConditionComponents(rule); populateNameConditionComponents(rule); populatePathConditionComponents(rule); + populateDateConditionComponents(rule); this.setButtons(okButton, cancelButton); } @@ -176,7 +180,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel { private void setOkButton() { if (this.okButton != null) { this.okButton.setEnabled(this.fileSizeCheck.isSelected() || this.mimeCheck.isSelected() - || this.nameCheck.isSelected() || this.pathCheck.isSelected()); + || this.nameCheck.isSelected() || this.pathCheck.isSelected() || this.dateCheck.isSelected()); } } @@ -274,6 +278,21 @@ final class FilesSetRulePanel extends javax.swing.JPanel { } } + /** + * Populates the UI components that display the optional date condition for + * a rule. + * + * @param rule The files set rule to be edited. + */ + private void populateDateConditionComponents(FilesSet.Rule rule) { + FilesSet.Rule.DateCondition dateCondition = rule.getDateCondition(); + if (dateCondition != null) { + this.dateCheck.setSelected(true); + this.dateCheckActionPerformed(null); + this.daysAgoTextField.setText(Integer.toString(dateCondition.getDaysAgo())); + } + } + /** * Returns whether or not the data entered in the panel constitutes a valid * files set membership rule definition, displaying a dialog explaining the @@ -283,7 +302,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel { */ boolean isValidRuleDefinition() { - if (!(this.mimeCheck.isSelected() || this.fileSizeCheck.isSelected() || this.pathCheck.isSelected() || this.nameCheck.isSelected())) { + if (!(this.mimeCheck.isSelected() || this.fileSizeCheck.isSelected() || this.pathCheck.isSelected() || this.nameCheck.isSelected() || this.dateCheck.isSelected())) { NotifyDescriptor notifyDesc = new NotifyDescriptor.Message( Bundle.FilesSetRulePanel_NoConditionError(), NotifyDescriptor.WARNING_MESSAGE); @@ -367,6 +386,25 @@ final class FilesSetRulePanel extends javax.swing.JPanel { } } + if (this.dateCheck.isSelected()) { + if (this.daysAgoTextField.getText().isEmpty()) { + NotifyDescriptor notifyDesc = new NotifyDescriptor.Message( + Bundle.FilesSetRulePanel_DaysAgoEmptyError(), + NotifyDescriptor.WARNING_MESSAGE); + DialogDisplayer.getDefault().notify(notifyDesc); + return false; + } + try { + Integer.parseInt(daysAgoTextField.getText()); + } catch (NumberFormatException e) { + //field did not contain an integer + NotifyDescriptor notifyDesc = new NotifyDescriptor.Message( + Bundle.FilesSetRulePanel_DaysAgoInvalidError(), + NotifyDescriptor.WARNING_MESSAGE); + DialogDisplayer.getDefault().notify(notifyDesc); + return false; + } + } return true; } @@ -504,6 +542,23 @@ final class FilesSetRulePanel extends javax.swing.JPanel { return condition; } + /** + * Gets the optional date condition for the rule that was created or edited. + * Should only be called if isValidDefintion() returns true. + * + * @return A date condition or null if no date condition was specified. + * + * @throws IllegalStateException if the specified date condition is not + * valid. + */ + FilesSet.Rule.DateCondition getDateCondition() { + FilesSet.Rule.DateCondition dateCondition = null; + if (!daysAgoTextField.getText().isEmpty()) { + dateCondition = new FilesSet.Rule.DateCondition(Integer.parseInt(daysAgoTextField.getText())); + } + return dateCondition; + } + /** * Checks an input string for the use of illegal characters. * @@ -582,15 +637,13 @@ final class FilesSetRulePanel extends javax.swing.JPanel { filesRadioButton = new javax.swing.JRadioButton(); dirsRadioButton = new javax.swing.JRadioButton(); allRadioButton = new javax.swing.JRadioButton(); + daysAgoTextField = new javax.swing.JTextField(); + daysAgoLabel = new javax.swing.JLabel(); + dateCheck = new javax.swing.JCheckBox(); org.openide.awt.Mnemonics.setLocalizedText(ruleNameLabel, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.ruleNameLabel.text")); // NOI18N ruleNameTextField.setText(org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.ruleNameTextField.text")); // NOI18N - ruleNameTextField.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - ruleNameTextFieldActionPerformed(evt); - } - }); org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.jLabel1.text")); // NOI18N @@ -685,85 +738,99 @@ final class FilesSetRulePanel extends javax.swing.JPanel { } }); + daysAgoTextField.setEnabled(false); + daysAgoTextField.setMinimumSize(new java.awt.Dimension(60, 20)); + daysAgoTextField.setPreferredSize(new java.awt.Dimension(60, 20)); + + org.openide.awt.Mnemonics.setLocalizedText(daysAgoLabel, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.daysAgoLabel.text")); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(dateCheck, org.openide.util.NbBundle.getMessage(FilesSetRulePanel.class, "FilesSetRulePanel.dateCheck.text")); // NOI18N + dateCheck.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + dateCheckActionPerformed(evt); + } + }); + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(8, 8, 8) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(ruleNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(ruleNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 234, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(ruleNameLabel) + .addGap(5, 5, 5) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(mimeTypeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pathTextField) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addComponent(equalitySymbolComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(fileSizeSpinner) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(fileSizeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addComponent(pathRegexCheckBox) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(pathSeparatorInfoLabel)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(daysAgoTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(daysAgoLabel)) + .addComponent(ruleNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 249, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addComponent(fullNameRadioButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(extensionRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 98, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(nameRegexCheckbox))) + .addGap(1, 1, 1)))) + .addComponent(jLabel5) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel5) + .addComponent(nameCheck, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1)) + .addGap(16, 16, 16) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1) - .addGap(65, 65, 65) .addComponent(filesRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(dirsRadioButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(allRadioButton))) - .addGap(0, 0, Short.MAX_VALUE)))) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(nameCheck) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addContainerGap() - .addComponent(pathCheck) - .addGap(4, 4, 4) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addComponent(pathRegexCheckBox) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(pathSeparatorInfoLabel)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(0, 0, Short.MAX_VALUE) - .addComponent(pathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addComponent(fullNameRadioButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(extensionRadioButton, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(nameRegexCheckbox) - .addGap(0, 0, Short.MAX_VALUE)))) + .addComponent(allRadioButton)) + .addComponent(nameTextField))))) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(pathCheck) .addComponent(mimeCheck) - .addComponent(fileSizeCheck)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(layout.createSequentialGroup() - .addComponent(equalitySymbolComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(fileSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(fileSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 82, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(mimeTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addComponent(fileSizeCheck) + .addComponent(dateCheck)) + .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jLabel5) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1) - .addComponent(filesRadioButton) - .addComponent(dirsRadioButton) - .addComponent(allRadioButton)) - .addGap(5, 5, 5) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(nameCheck)) + .addGap(3, 3, 3) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1) + .addGap(10, 10, 10) + .addComponent(nameCheck)) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(filesRadioButton) + .addComponent(dirsRadioButton) + .addComponent(allRadioButton)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(fullNameRadioButton) @@ -777,7 +844,7 @@ final class FilesSetRulePanel extends javax.swing.JPanel { .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(pathRegexCheckBox) .addComponent(pathSeparatorInfoLabel)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 8, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(mimeTypeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(mimeCheck)) @@ -787,7 +854,12 @@ final class FilesSetRulePanel extends javax.swing.JPanel { .addComponent(fileSizeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(fileSizeSpinner, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(fileSizeCheck)) - .addGap(15, 15, 15) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(daysAgoTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(daysAgoLabel) + .addComponent(dateCheck)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(ruleNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(ruleNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) @@ -795,10 +867,6 @@ final class FilesSetRulePanel extends javax.swing.JPanel { ); }// //GEN-END:initComponents - private void ruleNameTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_ruleNameTextFieldActionPerformed - // TODO add your handling code here: - }//GEN-LAST:event_ruleNameTextFieldActionPerformed - private void nameCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_nameCheckActionPerformed if (!this.nameCheck.isSelected()) { this.nameTextField.setEnabled(false); @@ -831,15 +899,30 @@ final class FilesSetRulePanel extends javax.swing.JPanel { this.setOkButton(); }//GEN-LAST:event_pathCheckActionPerformed - private void mimeCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mimeCheckActionPerformed - if (!this.mimeCheck.isSelected()) { - this.mimeTypeComboBox.setEnabled(false); - this.mimeTypeComboBox.setSelectedIndex(0); + private void filesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filesRadioButtonActionPerformed + + this.setComponentsForSearchType(); + }//GEN-LAST:event_filesRadioButtonActionPerformed + + private void dirsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dirsRadioButtonActionPerformed + this.setComponentsForSearchType(); + }//GEN-LAST:event_dirsRadioButtonActionPerformed + + private void allRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allRadioButtonActionPerformed + this.setComponentsForSearchType(); + }//GEN-LAST:event_allRadioButtonActionPerformed + + private void dateCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateCheckActionPerformed + if (!this.dateCheck.isSelected()) { + this.daysAgoTextField.setEnabled(false); + this.daysAgoLabel.setEnabled(false); + this.daysAgoTextField.setText(""); } else { - this.mimeTypeComboBox.setEnabled(true); + this.daysAgoTextField.setEnabled(true); + this.daysAgoLabel.setEnabled(true); } this.setOkButton(); - }//GEN-LAST:event_mimeCheckActionPerformed + }//GEN-LAST:event_dateCheckActionPerformed private void fileSizeCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileSizeCheckActionPerformed if (!this.fileSizeCheck.isSelected()) { @@ -855,21 +938,21 @@ final class FilesSetRulePanel extends javax.swing.JPanel { this.setOkButton(); }//GEN-LAST:event_fileSizeCheckActionPerformed - private void filesRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_filesRadioButtonActionPerformed - - this.setComponentsForSearchType(); - }//GEN-LAST:event_filesRadioButtonActionPerformed - - private void dirsRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dirsRadioButtonActionPerformed - this.setComponentsForSearchType(); - }//GEN-LAST:event_dirsRadioButtonActionPerformed - - private void allRadioButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allRadioButtonActionPerformed - this.setComponentsForSearchType(); - }//GEN-LAST:event_allRadioButtonActionPerformed + private void mimeCheckActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mimeCheckActionPerformed + if (!this.mimeCheck.isSelected()) { + this.mimeTypeComboBox.setEnabled(false); + this.mimeTypeComboBox.setSelectedIndex(0); + } else { + this.mimeTypeComboBox.setEnabled(true); + } + this.setOkButton(); + }//GEN-LAST:event_mimeCheckActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JRadioButton allRadioButton; + private javax.swing.JCheckBox dateCheck; + private javax.swing.JLabel daysAgoLabel; + private javax.swing.JTextField daysAgoTextField; private javax.swing.JRadioButton dirsRadioButton; private javax.swing.JComboBox equalitySymbolComboBox; private javax.swing.JRadioButton extensionRadioButton; diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetsManager.java b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetsManager.java index 6350805ee6..8397d77c72 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetsManager.java +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/FilesSetsManager.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2014 Basis Technology Corp. + * Copyright 2014-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -52,7 +52,7 @@ public final class FilesSetsManager extends Observable { { put(Bundle.FilesSetsManager_allFilesAndDirectories(), new Rule(Bundle.FilesSetsManager_allFilesAndDirectories(), null, - new MetaTypeCondition(MetaTypeCondition.Type.ALL), null, null, null)); + new MetaTypeCondition(MetaTypeCondition.Type.ALL), null, null, null, null)); } }); private static final FilesSet FILES_DIRS_UNALLOC_INGEST_FILTER = new FilesSet( @@ -61,7 +61,7 @@ public final class FilesSetsManager extends Observable { { put(Bundle.FilesSetsManager_allFilesDirectoriesAndUnallocated(), new Rule(Bundle.FilesSetsManager_allFilesDirectoriesAndUnallocated(), null, - new MetaTypeCondition(MetaTypeCondition.Type.ALL), null, null, null)); + new MetaTypeCondition(MetaTypeCondition.Type.ALL), null, null, null, null)); } }); diff --git a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemsFilesSetSettings.java b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemsFilesSetSettings.java index de88aee68e..d9a7393a95 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemsFilesSetSettings.java +++ b/Core/src/org/sleuthkit/autopsy/modules/interestingitems/InterestingItemsFilesSetSettings.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2017 Basis Technology Corp. + * Copyright 2011-2018 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -44,6 +44,7 @@ import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.FileSizeCond import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.MetaTypeCondition; import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.MimeTypeCondition; import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.ParentPathCondition; +import org.sleuthkit.autopsy.modules.interestingitems.FilesSet.Rule.DateCondition; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; @@ -67,6 +68,7 @@ class InterestingItemsFilesSetSettings implements Serializable { private static final String FILE_SET_TAG = "INTERESTING_FILE_SET"; //NON-NLS private static final String NAME_RULE_TAG = "NAME"; //NON-NLS private static final String NAME_ATTR = "name"; //NON-NLS + private static final String DAYS_AGO_ATTR = "daysAgo"; private static final String MIME_ATTR = "mimeType"; private static final String FS_COMPARATOR_ATTR = "comparatorSymbol"; private static final String FS_SIZE_ATTR = "sizeValue"; @@ -166,6 +168,35 @@ class InterestingItemsFilesSetSettings implements Serializable { return pathCondition; } + /** + * Construct a date condition for a FilesSet membership rule from data in an + * XML element. + * + * @param ruleElement The XML element. + * + * @return The date condition, or null if there is an error (logged). + * + * @throws + * org.sleuthkit.autopsy.modules.interestingitems.FilesSetsManager.FilesSetsManagerException + */ + private static DateCondition readDateCondition(Element ruleElement) throws FilesSetsManager.FilesSetsManagerException { + // Read in the optional path condition. Null is o.k., but if the attribute + // is there, be sure it is not malformed. + DateCondition dateCondition = null; + if (!ruleElement.getAttribute(DAYS_AGO_ATTR).isEmpty()) { + String daysAgo = ruleElement.getAttribute(DAYS_AGO_ATTR); + if (!daysAgo.isEmpty()) { + try { + dateCondition = new DateCondition(Integer.parseInt(daysAgo)); + } catch (NumberFormatException ex) { + logger.log(Level.SEVERE, "Error creating condition for " + daysAgo + ", ignoring malformed date condition definition", ex); // NON-NLS + throw new FilesSetsManager.FilesSetsManagerException(String.format("error compiling %s regex", DAYS_AGO_ATTR), ex); + } + } + } + return dateCondition; + } + /** * Attempts to compile a regular expression. * @@ -183,12 +214,13 @@ class InterestingItemsFilesSetSettings implements Serializable { } /** - * Construct a fileset membership rule from the data in an xml element for + * Construct a fileset membership rule from the data in an xml element for * use in a FilesSet. * * @param elem The XML element. * - * @return A file set constructed from the conditions available in the XML element + * @return A file set constructed from the conditions available in the XML + * element * * @throws * org.sleuthkit.autopsy.modules.interestingitems.FilesSetsManager.FilesSetsManagerException @@ -200,17 +232,17 @@ class InterestingItemsFilesSetSettings implements Serializable { ParentPathCondition pathCondition = readPathCondition(elem); MimeTypeCondition mimeCondition = readMimeCondition(elem); FileSizeCondition sizeCondition = readSizeCondition(elem); - //if meta type condition or all four types of conditions the user can create are all null then don't make the rule - if (metaCondition == null || (nameCondition == null && pathCondition == null && mimeCondition == null && sizeCondition == null)) { + DateCondition dateCondition = readDateCondition(elem); //if meta type condition or all four types of conditions the user can create are all null then don't make the rule + if (metaCondition == null || (nameCondition == null && pathCondition == null && mimeCondition == null && sizeCondition == null && dateCondition == null)) { logger.log(Level.WARNING, "Error Reading Rule, " + ruleName + " was either missing a meta condition or contained only a meta condition. No rule was imported."); // NON-NLS throw new FilesSetsManager.FilesSetsManagerException(String.format("Invalid Rule in FilesSet xml, missing necessary conditions for %s", ruleName)); } - return new FilesSet.Rule(ruleName, nameCondition, metaCondition, pathCondition, mimeCondition, sizeCondition); + return new FilesSet.Rule(ruleName, nameCondition, metaCondition, pathCondition, mimeCondition, sizeCondition, dateCondition); } /** - * Construct a file name condition for a FilesSet membership rule from data in an - * XML element. + * Construct a file name condition for a FilesSet membership rule from data + * in an XML element. * * @param ruleElement The XML element. * @@ -256,8 +288,8 @@ class InterestingItemsFilesSetSettings implements Serializable { } /** - * Construct a MIME type condition for a FilesSet membership rule from data in an - * XML element. + * Construct a MIME type condition for a FilesSet membership rule from data + * in an XML element. * * @param ruleElement The XML element. * @@ -275,8 +307,8 @@ class InterestingItemsFilesSetSettings implements Serializable { } /** - * Construct a file size condition for a FilesSet membership rule from data in an - * XML element. + * Construct a file size condition for a FilesSet membership rule from data + * in an XML element. * * @param ruleElement The XML element. *