diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java
index 1673fd577f..c723d99b55 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/DisplayableItemNode.java
@@ -51,7 +51,7 @@ public abstract class DisplayableItemNode extends AbstractNode {
*
* @throws TskCoreException
*/
- protected static AbstractFile findLinked(BlackboardArtifact artifact) throws TskCoreException {
+ static AbstractFile findLinked(BlackboardArtifact artifact) throws TskCoreException {
BlackboardAttribute pathIDAttribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID));
if (pathIDAttribute != null) {
long contentID = pathIDAttribute.getValueLong();
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java
index b703867a89..48c488c213 100644
--- a/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java
+++ b/Core/src/org/sleuthkit/autopsy/datamodel/accounts/Accounts.java
@@ -328,7 +328,8 @@ final public class Accounts implements AutopsyVisitableItem {
= "SELECT DISTINCT blackboard_attributes.value_text as account_type "
+ " FROM blackboard_artifacts " //NON-NLS
+ " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS
- + " WHERE blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID()
+ + " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_ACCOUNT.getTypeID() //NON-NLS
+ + " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_TYPE.getTypeID() //NON-NLS
+ getFilterByDataSourceClause();
try (SleuthkitCase.CaseDbQuery executeQuery = skCase.executeQuery(accountTypesInUseQuery);
diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java
index 14aceaf14f..11d61460a6 100644
--- a/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java
+++ b/Core/src/org/sleuthkit/autopsy/directorytree/DataResultFilterNode.java
@@ -567,7 +567,7 @@ public class DataResultFilterNode extends FilterNode {
// is a DirectoryTreeFilterNode that wraps the dataModelNode. We need
// to set that wrapped node as the selection and root context of the
// directory tree explorer manager (sourceEm)
- if(sourceEm == null) {
+ if(sourceEm == null || sourceEm.getSelectedNodes().length == 0) {
return null;
}
final Node currentSelectionInDirectoryTree = sourceEm.getSelectedNodes()[0];
diff --git a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/Bundle.properties-MERGED
index 708fbdb659..b12ce63db5 100644
--- a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/Bundle.properties-MERGED
+++ b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/Bundle.properties-MERGED
@@ -83,7 +83,7 @@ LogicalImagerDSProcessor.failToCreateDirectory=Failed to create directory {0}
LogicalImagerDSProcessor.imageDirPathNotFound={0} not found.\nUSB drive has been ejected.
LogicalImagerDSProcessor.noCurrentCase=No current case
LogicalImagerPanel.imageTable.columnModel.title0=Hostname
-LogicalImagerPanel.imageTable.columnModel.title1=Extracted Date
+LogicalImagerPanel.imageTable.columnModel.title1=Extracted Date (GMT)
LogicalImagerPanel.imageTable.columnModel.title2=Path
# {0} - sparseImageDirectory
LogicalImagerPanel.messageLabel.directoryDoesNotContainSparseImage=Directory {0} does not contain any images
diff --git a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerPanel.form b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerPanel.form
index 8f864e1f20..d8afe41c90 100644
--- a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerPanel.form
+++ b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerPanel.form
@@ -72,7 +72,7 @@
-
+
@@ -89,7 +89,7 @@
-
+
diff --git a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerPanel.java b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerPanel.java
index 6c5b374187..6a1198ea63 100644
--- a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerPanel.java
@@ -276,7 +276,7 @@ final class LogicalImagerPanel extends JPanel implements DocumentListener {
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 568, javax.swing.GroupLayout.PREFERRED_SIZE)))
- .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+ .addContainerGap(93, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
@@ -290,7 +290,7 @@ final class LogicalImagerPanel extends JPanel implements DocumentListener {
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(imageScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
- .addComponent(driveListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 23, Short.MAX_VALUE))
+ .addComponent(driveListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 198, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(refreshButton)
.addGap(18, 18, 18)
@@ -647,7 +647,7 @@ final class LogicalImagerPanel extends JPanel implements DocumentListener {
@Messages({
"LogicalImagerPanel.imageTable.columnModel.title0=Hostname",
- "LogicalImagerPanel.imageTable.columnModel.title1=Extracted Date",
+ "LogicalImagerPanel.imageTable.columnModel.title1=Extracted Date (GMT)",
"LogicalImagerPanel.imageTable.columnModel.title2=Path"
})
@Override
diff --git a/Core/src/org/sleuthkit/autopsy/report/NoReportModuleSettings.java b/Core/src/org/sleuthkit/autopsy/report/NoReportModuleSettings.java
index ad5fd9a09f..1415f2e8a7 100755
--- a/Core/src/org/sleuthkit/autopsy/report/NoReportModuleSettings.java
+++ b/Core/src/org/sleuthkit/autopsy/report/NoReportModuleSettings.java
@@ -32,13 +32,4 @@ public final class NoReportModuleSettings implements ReportModuleSettings {
return serialVersionUID;
}
- /**
- * Gets the string used as a report options placeholder for serialization
- * purposes.
- *
- * @return The string "None"
- */
- String getSetting() {
- return setting;
- }
}
diff --git a/Core/src/org/sleuthkit/autopsy/report/ReportBrandingProviderI.java b/Core/src/org/sleuthkit/autopsy/report/ReportBrandingProviderI.java
index 29c60c9256..7c495823e5 100644
--- a/Core/src/org/sleuthkit/autopsy/report/ReportBrandingProviderI.java
+++ b/Core/src/org/sleuthkit/autopsy/report/ReportBrandingProviderI.java
@@ -21,7 +21,7 @@ package org.sleuthkit.autopsy.report;
/**
* Interface to implement by reports to add on custom branding, logos, etc
*/
-public interface ReportBrandingProviderI {
+interface ReportBrandingProviderI {
/**
* Get the generator logo path on the local disk (previously set or
diff --git a/Core/src/org/sleuthkit/autopsy/report/modules/caseuco/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/report/modules/caseuco/Bundle.properties-MERGED
index 15625c1ad2..4543fa35f8 100755
--- a/Core/src/org/sleuthkit/autopsy/report/modules/caseuco/Bundle.properties-MERGED
+++ b/Core/src/org/sleuthkit/autopsy/report/modules/caseuco/Bundle.properties-MERGED
@@ -1,15 +1,18 @@
CaseUcoFormatExporter.finishMsg=Finished generating CASE-UCO Report
CaseUcoFormatExporter.startMsg=Generating CASE-UCO Report
OpenIDE-Module-Name=CaseUcoModule
+ReportCaseUco.databaseError=Failed to get list of files from case database
ReportCaseUco.datasourceMsg=Generating CASE-UCO Report for %s
ReportCaseUco.getName.text=CASE-UCO
ReportCaseUco.getDesc.text=CASE-UCO format report with basic property fields for every file.
ReportCaseUco.ingestWarning=Warning, this report will be created before ingest services completed
ReportCaseUco.initializing=Creating directories...
-ReportCaseUco.noCaseOpen=Unable to open currect case
+ReportCaseUco.jsonError=Failed to create JSON output for the CASE-UCO report
ReportCaseUco.noDataSourceSelected=No data source selected for CASE-UCO report
+ReportCaseUco.noOpenCase=No current case open
ReportCaseUco.notInitialized=CASE-UCO settings panel has not been initialized
ReportCaseUco.querying=Querying files...
+ReportCaseUco.resultSetError=Unable to read result set
ReportCaseUco.srcModuleName.text=CASE-UCO Report
ReportCaseUco.unableToCreateDirectories=Unable to create directory for CASE-UCO report
ReportCaseUcoConfigPanel.jLabelSelectDataSource.text=Select a data source for the CASE-UCO report
diff --git a/Core/src/org/sleuthkit/autopsy/report/modules/kml/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/report/modules/kml/Bundle.properties-MERGED
index c329b8ed7c..0823cd171b 100755
--- a/Core/src/org/sleuthkit/autopsy/report/modules/kml/Bundle.properties-MERGED
+++ b/Core/src/org/sleuthkit/autopsy/report/modules/kml/Bundle.properties-MERGED
@@ -1,3 +1,19 @@
+KMLReport.bookmarkError=Could not extract Bookmark information.
+# {0} - filePath
+KMLReport.errorGeneratingReport=Error adding {0} to case as a report.
+KMLReport.exifPhotoError=Could not extract photos with EXIF metadata.
+KMLReport.gpsBookmarkError=Could not get GPS Bookmarks from database.
+KMLReport.gpsRouteDatabaseError=Could not get GPS Routes from database.
+KMLReport.gpsRouteError=Could not extract GPS Route information.
+KMLReport.gpsSearchDatabaseError=Could not get GPS Searches from database.
+KMLReport.kmlFileWriteError=Could not write the KML file.
+KMLReport.locationDatabaseError=Could not get GPS Last Known Location from database.
+KMLReport.locationError=Could not extract Last Known Location information.
+KMLReport.stylesheetError=Error placing KML stylesheet. The .KML file will not function properly.
+KMLReport.trackpointDatabaseError=Could not get GPS Trackpoints from database.
+KMLReport.trackpointError=Could not extract Trackpoint information.
+KMLReport.unableToExtractPhotos=Could not extract photo information.
+KMLReport.unableToOpenCase=Exception while getting open case.
ReportKML.progress.querying=Querying files...
ReportKML.progress.loading=Loading files...
ReportKML.getName.text=Google Earth KML
diff --git a/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java b/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java
index ad7a61b52f..be05c59b67 100755
--- a/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java
+++ b/Core/src/org/sleuthkit/autopsy/timeline/explorernodes/EventNode.java
@@ -51,6 +51,7 @@ import org.sleuthkit.autopsy.timeline.actions.ViewFileInTimelineAction;
import org.sleuthkit.autopsy.timeline.ui.EventTypeUtils;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
+import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
@@ -175,6 +176,26 @@ public class EventNode extends DisplayableItemNode {
return actionsList.toArray(new Action[actionsList.size()]);
}
+ /**
+ * Gets the file, if any, linked to an artifact via a TSK_PATH_ID attribute
+ *
+ * @param artifact The artifact.
+ *
+ * @return An AbstractFile or null.
+ *
+ * @throws TskCoreException
+ */
+ private static AbstractFile findLinked(BlackboardArtifact artifact) throws TskCoreException {
+ BlackboardAttribute pathIDAttribute = artifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PATH_ID));
+ if (pathIDAttribute != null) {
+ long contentID = pathIDAttribute.getValueLong();
+ if (contentID != -1) {
+ return artifact.getSleuthkitCase().getAbstractFileById(contentID);
+ }
+ }
+ return null;
+ }
+
@Override
public boolean isLeafTypeNode() {
return true;
diff --git a/InternalPythonModules/android/TskCallLogsParser.py b/InternalPythonModules/android/TskCallLogsParser.py
index d4e6942134..6086073b02 100644
--- a/InternalPythonModules/android/TskCallLogsParser.py
+++ b/InternalPythonModules/android/TskCallLogsParser.py
@@ -37,7 +37,6 @@ class TskCallLogsParser(ResultSetIterator):
super(TskCallLogsParser, self).__init__(result_set)
self._DEFAULT_STRING = ""
self._DEFAULT_DIRECTION = CommunicationDirection.UNKNOWN
- self._DEFAULT_ADDRESS = None
self._DEFAULT_CALL_TYPE = CallMediaType.UNKNOWN
self._DEFAULT_LONG = -1L
@@ -50,10 +49,10 @@ class TskCallLogsParser(ResultSetIterator):
return self._DEFAULT_DIRECTION
def get_phone_number_from(self):
- return self._DEFAULT_ADDRESS
+ return self._DEFAULT_STRING
def get_phone_number_to(self):
- return self._DEFAULT_ADDRESS
+ return self._DEFAULT_STRING
def get_call_start_date_time(self):
return self._DEFAULT_LONG
diff --git a/InternalPythonModules/android/TskContactsParser.py b/InternalPythonModules/android/TskContactsParser.py
index 4e03613bcd..6db622d3ca 100644
--- a/InternalPythonModules/android/TskContactsParser.py
+++ b/InternalPythonModules/android/TskContactsParser.py
@@ -29,10 +29,9 @@ class TskContactsParser(ResultSetIterator):
def __init__(self, result_set):
super(TskContactsParser, self).__init__(result_set)
self._DEFAULT_VALUE = ""
- self._DEFAULT_ACCOUNT_ADDRESS = None
- def get_account_address(self):
- return self._DEFAULT_ACCOUNT_ADDRESS
+ def get_contact_name(self):
+ return self._DEFAULT_VALUE
def get_phone(self):
return self._DEFAULT_VALUE
@@ -45,3 +44,6 @@ class TskContactsParser(ResultSetIterator):
def get_email(self):
return self._DEFAULT_VALUE
+
+ def get_other_attributes(self):
+ return None
diff --git a/InternalPythonModules/android/TskMessagesParser.py b/InternalPythonModules/android/TskMessagesParser.py
index 4568a7400c..3887afd8b1 100644
--- a/InternalPythonModules/android/TskMessagesParser.py
+++ b/InternalPythonModules/android/TskMessagesParser.py
@@ -37,7 +37,6 @@ class TskMessagesParser(ResultSetIterator):
self._DEFAULT_TEXT = ""
self._DEFAULT_LONG = -1L
self._DEFAULT_MSG_READ_STATUS = MessageReadStatus.UNKNOWN
- self._DEFAULT_ACCOUNT_ADDRESS = None
self._DEFAULT_COMMUNICATION_DIRECTION = CommunicationDirection.UNKNOWN
self.INCOMING = CommunicationDirection.INCOMING
@@ -52,10 +51,10 @@ class TskMessagesParser(ResultSetIterator):
return self._DEFAULT_COMMUNICATION_DIRECTION
def get_phone_number_from(self):
- return self._DEFAULT_ACCOUNT_ADDRESS
+ return self._DEFAULT_TEXT
def get_phone_number_to(self):
- return self._DEFAULT_ACCOUNT_ADDRESS
+ return self._DEFAULT_TEXT
def get_message_date_time(self):
return self._DEFAULT_LONG
diff --git a/InternalPythonModules/android/fbmessenger.py b/InternalPythonModules/android/fbmessenger.py
index eb41cbd88a..3a678f16d0 100644
--- a/InternalPythonModules/android/fbmessenger.py
+++ b/InternalPythonModules/android/fbmessenger.py
@@ -174,9 +174,6 @@ class FBMessengerAnalyzer(general.AndroidComponentAnalyzer):
except TskCoreException as ex:
self._logger.log(Level.SEVERE, "Failed to add FB Messenger contact artifacts.", ex)
self._logger.log(Level.SEVERE, traceback.format_exc())
- except IllegalArgumentException as ex:
- self._logger.log(Level.WARNING, "Invalid arguments for FB Messenger contact artifact.", ex)
- self._logger.log(Level.WARNING, traceback.format_exc())
except BlackboardException as ex:
self._logger.log(Level.WARNING, "Failed to post artifacts.", ex)
self._logger.log(Level.WARNING, traceback.format_exc())
diff --git a/InternalPythonModules/android/line.py b/InternalPythonModules/android/line.py
index f8e826542f..ab8e24c9f9 100644
--- a/InternalPythonModules/android/line.py
+++ b/InternalPythonModules/android/line.py
@@ -139,14 +139,15 @@ class LineAnalyzer(general.AndroidComponentAnalyzer):
def parse_contacts(self, contacts_db, helper):
try:
- contacts_parser = LineContactsParser(contacts_db)
+ contacts_parser = LineContactsParser(contacts_db, self._PARSER_NAME)
while contacts_parser.next():
helper.addContact(
- contacts_parser.get_account_address(),
+ contacts_parser.get_contact_name(),
contacts_parser.get_phone(),
contacts_parser.get_home_phone(),
contacts_parser.get_mobile_phone(),
- contacts_parser.get_email()
+ contacts_parser.get_email(),
+ contacts_parser.get_other_attributes()
)
contacts_parser.close()
except SQLException as ex:
@@ -291,23 +292,14 @@ class LineCallLogsParser(TskCallLogsParser):
group_members = self.result_set.getString("group_members")
if group_members is not None:
group_members = group_members.split(",")
- group_names = self.result_set.getString("names").split(",")
+ return group_members
- recipients = []
-
- for member_id, member_name in zip(group_members, group_names):
- recipients.append(Account.Address(member_id, member_name))
-
- return recipients
-
- return Account.Address(self.result_set.getString("caller_mid"),
- self.result_set.getString("names"))
+ return self.result_set.getString("caller_mid")
return super(LineCallLogsParser, self).get_phone_number_to()
def get_phone_number_from(self):
if self.get_call_direction() == self.INCOMING_CALL:
- return Account.Address(self.result_set.getString("caller_mid"),
- self.result_set.getString("names"))
+ return self.result_set.getString("caller_mid")
return super(LineCallLogsParser, self).get_phone_number_from()
def get_call_type(self):
@@ -331,7 +323,7 @@ class LineContactsParser(TskContactsParser):
a default value inherited from the super class.
"""
- def __init__(self, contact_db):
+ def __init__(self, contact_db, analyzer):
super(LineContactsParser, self).__init__(contact_db.runQuery(
"""
SELECT m_id,
@@ -341,9 +333,17 @@ class LineContactsParser(TskContactsParser):
)
)
- def get_account_address(self):
- return Account.Address(self.result_set.getString("m_id"),
- self.result_set.getString("server_name"))
+ self._PARENT_ANALYZER = analyzer
+
+ def get_contact_name(self):
+ return self.result_set.getString("server_name")
+
+ def get_other_attributes(self):
+ return [BlackboardAttribute(
+ BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID,
+ self._PARENT_ANALYZER,
+ self.result_set.getString("m_id"))]
+
class LineMessagesParser(TskMessagesParser):
"""
@@ -430,8 +430,7 @@ class LineMessagesParser(TskMessagesParser):
if self.get_message_direction() == self.INCOMING:
from_mid = self.result_set.getString("from_mid")
if from_mid is not None:
- return Account.Address(from_mid,
- self.result_set.getString("from_name"))
+ return from_mid
return super(LineMessagesParser, self).get_phone_number_from()
def get_phone_number_to(self):
@@ -439,17 +438,9 @@ class LineMessagesParser(TskMessagesParser):
group = self.result_set.getString("members")
if group is not None:
group = group.split(",")
- names = self.result_set.getString("member_names").split(",")
-
- recipients = []
+ return group
- for recipient_id, recipient_name in zip(group, names):
- recipients.append(Account.Address(recipient_id, recipient_name))
-
- return recipients
-
- return Account.Address(self.result_set.getString("id"),
- self.result_set.getString("name"))
+ return self.result_set.getString("id")
return super(LineMessagesParser, self).get_phone_number_to()
diff --git a/InternalPythonModules/android/skype.py b/InternalPythonModules/android/skype.py
index fe027961ff..5044898d5f 100644
--- a/InternalPythonModules/android/skype.py
+++ b/InternalPythonModules/android/skype.py
@@ -99,8 +99,7 @@ class SkypeAnalyzer(general.AndroidComponentAnalyzer):
)
if account_query_result is not None and account_query_result.next():
- return Account.Address(account_query_result.getString("entry_id"),
- account_query_result.getString("name"))
+ return account_query_result.getString("entry_id")
return None
def analyze(self, dataSource, fileManager, context):
@@ -148,14 +147,15 @@ class SkypeAnalyzer(general.AndroidComponentAnalyzer):
#Query for contacts and iterate row by row adding
#each contact artifact
try:
- contacts_parser = SkypeContactsParser(skype_db)
+ contacts_parser = SkypeContactsParser(skype_db, self._PARSER_NAME)
while contacts_parser.next():
helper.addContact(
- contacts_parser.get_account_address(),
+ contacts_parser.get_contact_name(),
contacts_parser.get_phone(),
contacts_parser.get_home_phone(),
contacts_parser.get_mobile_phone(),
- contacts_parser.get_email()
+ contacts_parser.get_email(),
+ contacts_parser.get_other_attributes()
)
contacts_parser.close()
except SQLException as ex:
@@ -306,25 +306,17 @@ class SkypeCallLogsParser(TskCallLogsParser):
def get_phone_number_from(self):
if self.get_call_direction() == self.INCOMING_CALL:
- return Account.Address(self.result_set.getString("sender_id"),
- self.result_set.getString("sender_name"))
+ return self.result_set.getString("sender_id")
def get_phone_number_to(self):
if self.get_call_direction() == self.OUTGOING_CALL:
group_ids = self.result_set.getString("participant_ids")
- name = self.result_set.getString("participants")
if group_ids is not None:
group_ids = group_ids.split(",")
- name = name.split(",")
- recipients = []
-
- for person_id, person_name in zip(group_ids, name):
- recipients.append(Account.Address(person_id, person_name))
-
- return recipients
+ return group_ids
- return Account.Address(self.result_set.getString("conversation_id"), name)
+ return self.result_set.getString("conversation_id")
return super(SkypeCallLogsParser, self).get_phone_number_to()
@@ -351,7 +343,7 @@ class SkypeContactsParser(TskContactsParser):
a default value inherited from the super class.
"""
- def __init__(self, contact_db):
+ def __init__(self, contact_db, analyzer):
super(SkypeContactsParser, self).__init__(contact_db.runQuery(
"""
SELECT entry_id,
@@ -360,10 +352,17 @@ class SkypeContactsParser(TskContactsParser):
"""
)
)
+ self._PARENT_ANALYZER = analyzer
- def get_account_address(self):
- return Account.Address(self.result_set.getString("entry_id"),
- self.result_set.getString("name"))
+ def get_contact_name(self):
+ return self.result_set.getString("name")
+
+ def get_other_attributes(self):
+ return [BlackboardAttribute(
+ BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID,
+ self._PARENT_ANALYZER,
+ self.result_set.getString("entry_id"))]
+
class SkypeMessagesParser(TskMessagesParser):
"""
@@ -424,8 +423,7 @@ class SkypeMessagesParser(TskMessagesParser):
def get_phone_number_from(self):
if self.get_message_direction() == self.INCOMING:
- return Account.Address(self.result_set.getString("sender_id"),
- self.result_set.getString("sender_name"))
+ return self.result_set.getString("sender_id")
return super(SkypeMessagesParser, self).get_phone_number_from()
def get_message_direction(self):
@@ -439,19 +437,12 @@ class SkypeMessagesParser(TskMessagesParser):
def get_phone_number_to(self):
if self.get_message_direction() == self.OUTGOING:
group_ids = self.result_set.getString("participant_ids")
- names = self.result_set.getString("participants")
if group_ids is not None:
group_ids = group_ids.split(",")
- names = names.split(",")
- recipients = []
-
- for participant_id, participant_name in zip(group_ids, names):
- recipients.append(Account.Address(participant_id, participant_name))
-
- return recipients
+ return group_ids
- return Account.Address(self.result_set.getString("conversation_id"), names)
+ return self.result_set.getString("conversation_id")
return super(SkypeMessagesParser, self).get_phone_number_to()
diff --git a/InternalPythonModules/android/textnow.py b/InternalPythonModules/android/textnow.py
index 8361b0d3eb..ad9704cece 100644
--- a/InternalPythonModules/android/textnow.py
+++ b/InternalPythonModules/android/textnow.py
@@ -108,7 +108,7 @@ class TextNowAnalyzer(general.AndroidComponentAnalyzer):
contacts_parser = TextNowContactsParser(textnow_db)
while contacts_parser.next():
helper.addContact(
- contacts_parser.get_account_address(),
+ contacts_parser.get_contact_name(),
contacts_parser.get_phone(),
contacts_parser.get_home_phone(),
contacts_parser.get_mobile_phone(),
@@ -220,14 +220,12 @@ class TextNowCallLogsParser(TskCallLogsParser):
def get_phone_number_from(self):
if self.get_call_direction() == self.OUTGOING_CALL:
return super(TextNowCallLogsParser, self).get_phone_number_from()
- return Account.Address(self.result_set.getString("num"),
- self.result_set.getString("num"))
+ return self.result_set.getString("num")
def get_phone_number_to(self):
if self.get_call_direction() == self.INCOMING_CALL:
return super(TextNowCallLogsParser, self).get_phone_number_to()
- return Account.Address(self.result_set.getString("num"),
- self.result_set.getString("num"))
+ return self.result_set.getString("num")
def get_call_direction(self):
if self.result_set.getInt("direction") == self._INCOMING_CALL_TYPE:
@@ -266,9 +264,8 @@ class TextNowContactsParser(TskContactsParser):
)
)
- def get_account_address(self):
- return Account.Address(self.result_set.getString("number"),
- self.result_set.getString("name"))
+ def get_contact_name(self):
+ return self.result_set.getString("name")
def get_phone(self):
return self.result_set.getString("number")
@@ -341,8 +338,7 @@ class TextNowMessagesParser(TskMessagesParser):
def get_phone_number_from(self):
if self.result_set.getString("from_address") == "":
return super(TextNowMessagesParser, self).get_phone_number_from()
- return Account.Address(self.result_set.getString("from_address"),
- self.result_set.getString("from_address"))
+ return self.result_set.getString("from_address")
def get_message_direction(self):
direction = self.result_set.getInt("message_direction")
@@ -354,12 +350,7 @@ class TextNowMessagesParser(TskMessagesParser):
if self.result_set.getString("to_address") == "":
return super(TextNowMessagesParser, self).get_phone_number_to()
recipients = self.result_set.getString("to_address").split(",")
-
- recipient_accounts = []
- for recipient in recipients:
- recipient_accounts.append(Account.Address(recipient, recipient))
-
- return recipient_accounts
+ return recipients
def get_message_date_time(self):
#convert ms to s
diff --git a/InternalPythonModules/android/viber.py b/InternalPythonModules/android/viber.py
index 54f0b260a0..f922b3508e 100644
--- a/InternalPythonModules/android/viber.py
+++ b/InternalPythonModules/android/viber.py
@@ -116,7 +116,7 @@ class ViberAnalyzer(general.AndroidComponentAnalyzer):
contacts_parser = ViberContactsParser(contacts_db)
while contacts_parser.next():
helper.addContact(
- contacts_parser.get_account_address(),
+ contacts_parser.get_contact_name(),
contacts_parser.get_phone(),
contacts_parser.get_home_phone(),
contacts_parser.get_mobile_phone(),
@@ -217,16 +217,14 @@ class ViberCallLogsParser(TskCallLogsParser):
def get_phone_number_from(self):
if self.get_call_direction() == self.INCOMING_CALL:
- return Account.Address(self.result_set.getString("number"),
- self.result_set.getString("number"))
+ return self.result_set.getString("number")
#Give default value if the call is outgoing,
#the device's # is not stored in the database.
return super(ViberCallLogsParser, self).get_phone_number_from()
def get_phone_number_to(self):
if self.get_call_direction() == self.OUTGOING_CALL:
- return Account.Address(self.result_set.getString("number"),
- self.result_set.getString("number"))
+ return self.result_set.getString("number")
#Give default value if the call is incoming,
#the device's # is not stored in the database.
return super(ViberCallLogsParser, self).get_phone_number_to()
@@ -272,9 +270,8 @@ class ViberContactsParser(TskContactsParser):
)
)
- def get_account_address(self):
- return Account.Address(self.result_set.getString("number"),
- self.result_set.getString("name"))
+ def get_contact_name(self):
+ return self.result_set.getString("name")
def get_phone(self):
return self.result_set.getString("number")
@@ -339,8 +336,7 @@ class ViberMessagesParser(TskMessagesParser):
return self._VIBER_MESSAGE_TYPE
def get_phone_number_from(self):
- return Account.Address(self.result_set.getString("from_number"),
- self.result_set.getString("from_number"))
+ return self.result_set.getString("from_number")
def get_message_direction(self):
direction = self.result_set.getInt("direction")
@@ -349,10 +345,7 @@ class ViberMessagesParser(TskMessagesParser):
return self.OUTGOING
def get_phone_number_to(self):
- recipients = []
- for token in self.result_set.getString("recipients").split(","):
- recipients.append(Account.Address(token, token))
- return recipients
+ return self.result_set.getString("recipients").split(",")
def get_message_date_time(self):
#transform from ms to seconds
diff --git a/InternalPythonModules/android/whatsapp.py b/InternalPythonModules/android/whatsapp.py
index 09f2521a8d..9cb7ea3d73 100644
--- a/InternalPythonModules/android/whatsapp.py
+++ b/InternalPythonModules/android/whatsapp.py
@@ -167,14 +167,15 @@ class WhatsAppAnalyzer(general.AndroidComponentAnalyzer):
def parse_contacts(self, contacts_db, helper):
try:
- contacts_parser = WhatsAppContactsParser(contacts_db)
+ contacts_parser = WhatsAppContactsParser(contacts_db, self._PARSER_NAME)
while contacts_parser.next():
helper.addContact(
- contacts_parser.get_account_address(),
+ contacts_parser.get_contact_name(),
contacts_parser.get_phone(),
contacts_parser.get_home_phone(),
contacts_parser.get_mobile_phone(),
- contacts_parser.get_email()
+ contacts_parser.get_email(),
+ contacts_parser.get_other_attributes()
)
contacts_parser.close()
except SQLException as ex:
@@ -295,16 +296,14 @@ class WhatsAppGroupCallLogsParser(TskCallLogsParser):
def get_phone_number_from(self):
if self.get_call_direction() == self.INCOMING_CALL:
sender = self.result_set.getString("from_id")
- return Account.Address(sender, sender)
+ return sender
return super(WhatsAppGroupCallLogsParser, self).get_phone_number_from()
def get_phone_number_to(self):
if self.get_call_direction() == self.OUTGOING_CALL:
+ #group_members column stores comma seperated list of groups or single contact
group = self.result_set.getString("group_members")
- members = []
- for token in group.split(","):
- members.append(Account.Address(token, token))
- return members
+ return group.split(",")
return super(WhatsAppGroupCallLogsParser, self).get_phone_number_to()
def get_call_start_date_time(self):
@@ -354,13 +353,13 @@ class WhatsAppSingleCallLogsParser(TskCallLogsParser):
def get_phone_number_from(self):
if self.get_call_direction() == self.INCOMING_CALL:
sender = self.result_set.getString("num")
- return Account.Address(sender, sender)
+ return sender
return super(WhatsAppSingleCallLogsParser, self).get_phone_number_from()
def get_phone_number_to(self):
if self.get_call_direction() == self.OUTGOING_CALL:
to = self.result_set.getString("num")
- return Account.Address(to, to)
+ return to
return super(WhatsAppSingleCallLogsParser, self).get_phone_number_to()
def get_call_start_date_time(self):
@@ -384,7 +383,7 @@ class WhatsAppContactsParser(TskContactsParser):
a default value inherited from the super class.
"""
- def __init__(self, contact_db):
+ def __init__(self, contact_db, analyzer):
super(WhatsAppContactsParser, self).__init__(contact_db.runQuery(
"""
SELECT jid,
@@ -409,14 +408,21 @@ class WhatsAppContactsParser(TskContactsParser):
"""
)
)
+
+ self._PARENT_ANALYZER = analyzer
- def get_account_address(self):
- return Account.Address(self.result_set.getString("jid"),
- self.result_set.getString("name"))
+ def get_contact_name(self):
+ return self.result_set.getString("name")
def get_phone(self):
return self.result_set.getString("number")
+ def get_other_attributes(self):
+ return [BlackboardAttribute(
+ BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ID,
+ self._PARENT_ANALYZER,
+ self.result_set.getString("jid"))]
+
class WhatsAppMessagesParser(TskMessagesParser):
"""
Extract TSK_MESSAGE information from the WhatsApp database.
@@ -468,15 +474,9 @@ class WhatsAppMessagesParser(TskMessagesParser):
group = self.result_set.getString("recipients")
if group is not None:
group = group.split(",")
-
- recipients = []
- for token in group:
- recipients.append(Account.Address(token, token))
-
- return recipients
+ return group
- return Account.Address(self.result_set.getString("id"),
- self.result_set.getString("id"))
+ return self.result_set.getString("id")
return super(WhatsAppMessagesParser, self).get_phone_number_to()
def get_phone_number_from(self):
@@ -484,10 +484,9 @@ class WhatsAppMessagesParser(TskMessagesParser):
group_sender = self.result_set.getString("group_sender")
group = self.result_set.getString("recipients")
if group_sender is not None and group is not None:
- return Account.Address(group_sender, group_sender)
+ return group_sender
else:
- return Account.Address(self.result_set.getString("id"),
- self.result_set.getString("id"))
+ return self.result_set.getString("id")
return super(WhatsAppMessagesParser, self).get_phone_number_from()
def get_message_direction(self):
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED
index e5c93303b3..5cfd965ac8 100755
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED
@@ -36,7 +36,7 @@ KeywordSearchResultFactory.createNodeForKey.noResultsFound.text=No results found
KeywordSearchResultFactory.query.exception.msg=Could not perform the query
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
OptionsCategory_Name_KeywordSearchOptions=Keyword Search
OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search
diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED
index 805e776717..4f2d1d4fd9 100755
--- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED
+++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/Bundle.properties-MERGED
@@ -2,14 +2,9 @@ cannotBuildXmlParser=Unable to build XML parser:
cannotLoadSEUQA=Unable to load Search Engine URL Query Analyzer settings file, SEUQAMappings.xml:
cannotParseXml=Unable to parse XML file:
ChromeCacheExtractor.moduleName=ChromeCacheExtractor
-# {0} - module name
-# {1} - row number
-# {2} - table length
-# {3} - cache path
ChromeCacheExtractor.progressMsg={0}: Extracting cache entry {1} of {2} entries from {3}
DataSourceUsage_AndroidMedia=Android Media Card
DataSourceUsage_FlashDrive=Flash Drive
-# {0} - OS name
DataSourceUsageAnalyzer.customVolume.label=OS Drive ({0})
DataSourceUsageAnalyzer.parentModuleName=Recent Activity
Extract.indexError.message=Failed to index artifact for keyword search.
@@ -188,7 +183,6 @@ RecentDocumentsByLnk.parentModuleName.noSpace=RecentActivity
RecentDocumentsByLnk.parentModuleName=Recent Activity
RegRipperFullNotFound=Full version RegRipper executable not found.
RegRipperNotFound=Autopsy RegRipper executable not found.
-# {0} - file name
SearchEngineURLQueryAnalyzer.init.exception.msg=Unable to find {0}.
SearchEngineURLQueryAnalyzer.moduleName.text=Search Engine
SearchEngineURLQueryAnalyzer.engineName.none=NONE
diff --git a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ShellBagParser.java b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ShellBagParser.java
index a7de5ebf5c..5f8f2eb38f 100755
--- a/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ShellBagParser.java
+++ b/RecentActivity/src/org/sleuthkit/autopsy/recentactivity/ShellBagParser.java
@@ -37,12 +37,12 @@ import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Parse the ntuser and ursclass regripper output files for shellbags.
*/
-public class ShellBagParser {
+class ShellBagParser {
private static final Logger logger = Logger.getLogger(ShellBagParser.class.getName());
- static SimpleDateFormat DATE_TIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
+ private static final SimpleDateFormat DATE_TIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
// Last Write date\time format from itempos plugin
- static SimpleDateFormat DATE_TIME_FORMATTER2 = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyyy", Locale.getDefault());
+ private static final SimpleDateFormat DATE_TIME_FORMATTER2 = new SimpleDateFormat("EEE MMM dd HH:mm:ss yyyyy", Locale.getDefault());
private ShellBagParser() {
}
diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
index 76d2f2846d..158d4a62d7 100644
--- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
+++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
@@ -1,5 +1,5 @@
#Updated by build script
-#Fri, 07 Jun 2019 14:47:12 -0400
+#Wed, 02 Oct 2019 12:06:32 -0400
LBL_splash_window_title=Starting Autopsy
SPLASH_HEIGHT=314
SPLASH_WIDTH=538
@@ -8,4 +8,4 @@ SplashRunningTextBounds=0,289,538,18
SplashRunningTextColor=0x0
SplashRunningTextFontSize=19
-currentVersion=Autopsy 4.11.0
+currentVersion=Autopsy 4.13.0
diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
index 1da6c75411..3f60232032 100644
--- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
+++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
@@ -1,4 +1,4 @@
#Updated by build script
-#Fri, 07 Jun 2019 14:47:12 -0400
-CTL_MainWindow_Title=Autopsy 4.11.0
-CTL_MainWindow_Title_No_Project=Autopsy 4.11.0
+#Wed, 02 Oct 2019 12:06:32 -0400
+CTL_MainWindow_Title=Autopsy 4.13.0
+CTL_MainWindow_Title_No_Project=Autopsy 4.13.0
diff --git a/docs/doxygen-user/portable_case.dox b/docs/doxygen-user/portable_case.dox
index 34dcc7bf57..de90443026 100644
--- a/docs/doxygen-user/portable_case.dox
+++ b/docs/doxygen-user/portable_case.dox
@@ -33,7 +33,7 @@ You can tag any additional files you want to include in the portable case. See t
\image html portable_case_tags.png
-Portable cases are created through the \ref reporting_page feature. The Generate Report dialog will display a list of all tags and interesting file sets that are in use in the current case and you can choose which ones you would like to include. At the bottom you can choose to optionally package the case. Choosing to package the case without chunking will simply compress the portable case in a single archive that can be extracted with common compression programs. If you choose split the packaged case into multiple files, you will need to use the "Unpackage Portable Case" option before loading it. This will be discussed in the next section.
+Portable cases are created through the \ref reporting_page feature. The Generate Report dialog will display a list of all tags and interesting file sets that are in use in the current case and you can choose which ones you would like to include. At the bottom you can choose to optionally package the case. Choosing to package the case without chunking will simply compress the portable case in a single archive that can be extracted with common compression programs. If you choose split the packaged case into multiple files, you will need to use the "Unpack and Open Portable Case" option to open it. This will be discussed in the next section.
The portable case will be placed in the "Reports" folder in the current case.
@@ -49,7 +49,7 @@ If you packaged the portable case but did not choose to split it into chunks, yo
\section portable_case_usage Using a Portable Case
-If your portable case was packaged, you'll first need to unpackage it. Open the "Case" menu and then select "Unpackage Portable Case". This will bring up a dialog where you can browse to your packaged case and select where to extract it to. Once unpackaged you can open it normally.
+Unpackaged portable cases can be opened like any other case through Case->Open Case. If your portable case was packaged, you'll need to use the unpack option to open it. Open the "Case" menu and then select "Unpack and Open Portable Case" option. This will bring up a dialog where you can browse to your packaged case and select where to extract it to. The case will also open. Note that any changes made to the case at this point will be saved to the unpacked location, and next time you open it you will need to browse to the unpacked folder.
\image html portable_case_unpackage.png
diff --git a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/Bundle.properties-MERGED b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/Bundle.properties-MERGED
index 18a00e9d3e..cdfd241886 100755
--- a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/Bundle.properties-MERGED
+++ b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/Bundle.properties-MERGED
@@ -12,6 +12,8 @@ PstParser.noOpenCase.errMsg=Exception while getting open case.
PstParser.parse.errMsg.failedToParseNMsgs=Failed to extract {0} email messages.
PstParser.extractAttch.errMsg.failedToExtractToDisk=Failed to extract PST attachment to disk: {0}
ThunderbirdMboxFileIngestModule.addArtifact.indexError.message=Failed to index email message detected artifact for keyword search.
+# {0} - file name
+# {1} - file ID
ThunderbirdMboxFileIngestModule.errorMessage.outOfDiskSpace=Out of disk space. Cannot copy '{0}' (id={1}) to parse.
ThunderbirdMboxFileIngestModule.moduleName=Email Parser
ThunderbirdMboxFileIngestModule.noOpenCase.errMsg=Exception while getting open case.