Merge pull request #3482 from dgrove727/3437_ReadContentInputStreamError_1

3437 read content input stream error 1
This commit is contained in:
Richard Cordovano 2018-03-06 10:09:08 -05:00 committed by GitHub
commit f93bfe9965
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 219 additions and 119 deletions

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011-2017 Basis Technology Corp.
* Copyright 2011-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -44,6 +44,7 @@ import org.sleuthkit.datamodel.LayoutFile;
import org.sleuthkit.datamodel.LocalFile;
import org.sleuthkit.datamodel.LocalDirectory;
import org.sleuthkit.datamodel.ReadContentInputStream;
import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
import org.sleuthkit.datamodel.SlackFile;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.VirtualDirectory;
@ -69,18 +70,20 @@ public final class ContentUtils {
});
}
// don't instantiate
/**
* Don't instantiate
*/
private ContentUtils() {
throw new AssertionError();
}
/**
* Convert epoch seconds to a string value in the given time zone
* Convert epoch seconds to a string value in the given time zone.
*
* @param epochSeconds
* @param tzone
* @param epochSeconds Epoch seconds
* @param tzone Time zone
*
* @return
* @return The time
*/
public static String getStringTime(long epochSeconds, TimeZone tzone) {
String time = "0000-00-00 00:00:00";
@ -93,6 +96,14 @@ public final class ContentUtils {
return time;
}
/**
* Convert epoch seconds to a string value (ISO8601) in the given time zone.
*
* @param epochSeconds Epoch seconds
* @param tzone Time zone
*
* @return The time
*/
public static String getStringTimeISO8601(long epochSeconds, TimeZone tzone) {
String time = "0000-00-00T00:00:00Z"; //NON-NLS
if (epochSeconds != 0) {
@ -109,12 +120,12 @@ public final class ContentUtils {
* Convert epoch seconds to a string value (convenience method)
*
* @param epochSeconds
* @param c
* @param content
*
* @return
*/
public static String getStringTime(long epochSeconds, Content c) {
return getStringTime(epochSeconds, getTimeZone(c));
public static String getStringTime(long epochSeconds, Content content) {
return getStringTime(epochSeconds, getTimeZone(content));
}
/**
@ -130,13 +141,13 @@ public final class ContentUtils {
return getStringTimeISO8601(epochSeconds, getTimeZone(c));
}
public static TimeZone getTimeZone(Content c) {
public static TimeZone getTimeZone(Content content) {
try {
if (!shouldDisplayTimesInLocalTime()) {
return TimeZone.getTimeZone("GMT");
} else {
final Content dataSource = c.getDataSource();
final Content dataSource = content.getDataSource();
if ((dataSource != null) && (dataSource instanceof Image)) {
Image image = (Image) dataSource;
return TimeZone.getTimeZone(image.getTimeZone());
@ -151,10 +162,21 @@ public final class ContentUtils {
}
private static final SystemNameVisitor systemName = new SystemNameVisitor();
/**
* Get system name from content using SystemNameVisitor.
*
* @param content The content object.
*
* @return The system name.
*/
public static String getSystemName(Content content) {
return content.accept(systemName);
}
/**
* Visitor designed to handle the system name (content name and ID
* appended).
*/
private static class SystemNameVisitor extends ContentVisitor.Default<String> {
SystemNameVisitor() {
@ -220,27 +242,37 @@ public final class ContentUtils {
return totalRead;
}
/**
* Write content to an output file.
*
* @param content The Content object.
* @param outputFile The output file.
*
* @throws IOException If the file could not be written.
*/
public static void writeToFile(Content content, java.io.File outputFile) throws IOException {
writeToFile(content, outputFile, null, null, false);
}
/**
* Reads all the data from any content object and writes (extracts) it to a
* file, using a cancellation check instead of a Future object method.
*
*
* @param content Any content object.
* @param outputFile Will be created if it doesn't exist, and overwritten
* if it does
* @param cancelCheck A function used to check if the file write process
* should be terminated.
*
* @return number of bytes extracted
*
* @throws IOException if file could not be written
*/
public static long writeToFile(Content content, java.io.File outputFile,
Supplier<Boolean> cancelCheck) throws IOException {
InputStream in = new ReadContentInputStream(content);
long totalRead = 0;
try (FileOutputStream out = new FileOutputStream(outputFile, false)) {
byte[] buffer = new byte[TO_FILE_BUFFER_SIZE];
int len = in.read(buffer);
@ -260,7 +292,9 @@ public final class ContentUtils {
/**
* Helper to ignore the '.' and '..' directories
* @param dir the directory to check
*
* @param dir the directory to check
*
* @return true if dir is a '.' or '..' directory, false otherwise
*/
public static boolean isDotDirectory(AbstractFile dir) {
@ -313,61 +347,81 @@ public final class ContentUtils {
}
@Override
public Void visit(File f) {
public Void visit(File file) {
try {
ContentUtils.writeToFile(f, dest, progress, worker, source);
ContentUtils.writeToFile(file, dest, progress, worker, source);
} catch (ReadContentInputStreamException ex) {
logger.log(Level.WARNING,
String.format("Error reading file '%s' (id=%d).",
file.getName(), file.getId()), ex); //NON-NLS
} catch (IOException ex) {
logger.log(Level.SEVERE,
"Trouble extracting file to " + dest.getAbsolutePath(), //NON-NLS
ex);
String.format("Error extracting file '%s' (id=%d) to '%s'.",
file.getName(), file.getId(), dest.getAbsolutePath()), ex); //NON-NLS
}
return null;
}
@Override
public Void visit(LayoutFile f) {
public Void visit(LayoutFile file) {
try {
ContentUtils.writeToFile(f, dest, progress, worker, source);
ContentUtils.writeToFile(file, dest, progress, worker, source);
} catch (ReadContentInputStreamException ex) {
logger.log(Level.WARNING,
String.format("Error reading file '%s' (id=%d).",
file.getName(), file.getId()), ex); //NON-NLS
} catch (IOException ex) {
logger.log(Level.SEVERE,
"Trouble extracting unallocated content file to " + dest.getAbsolutePath(), //NON-NLS
ex);
String.format("Error extracting unallocated content file '%s' (id=%d) to '%s'.",
file.getName(), file.getId(), dest.getAbsolutePath()), ex); //NON-NLS
}
return null;
}
@Override
public Void visit(DerivedFile df) {
public Void visit(DerivedFile file) {
try {
ContentUtils.writeToFile(df, dest, progress, worker, source);
ContentUtils.writeToFile(file, dest, progress, worker, source);
} catch (ReadContentInputStreamException ex) {
logger.log(Level.WARNING,
String.format("Error reading file '%s' (id=%d).",
file.getName(), file.getId()), ex); //NON-NLS
} catch (IOException ex) {
logger.log(Level.SEVERE,
"Error extracting derived file to " + dest.getAbsolutePath(), //NON-NLS
ex);
String.format("Error extracting derived file '%s' (id=%d) to '%s'.",
file.getName(), file.getId(), dest.getAbsolutePath()), ex); //NON-NLS
}
return null;
}
@Override
public Void visit(LocalFile lf) {
public Void visit(LocalFile file) {
try {
ContentUtils.writeToFile(lf, dest, progress, worker, source);
ContentUtils.writeToFile(file, dest, progress, worker, source);
} catch (ReadContentInputStreamException ex) {
logger.log(Level.WARNING,
String.format("Error reading file '%s' (id=%d).",
file.getName(), file.getId()), ex); //NON-NLS
} catch (IOException ex) {
logger.log(Level.SEVERE,
"Error extracting local file to " + dest.getAbsolutePath(), //NON-NLS
ex);
String.format("Error extracting local file '%s' (id=%d) to '%s'.",
file.getName(), file.getId(), dest.getAbsolutePath()), ex); //NON-NLS
}
return null;
}
@Override
public Void visit(SlackFile f) {
public Void visit(SlackFile file) {
try {
ContentUtils.writeToFile(f, dest, progress, worker, source);
ContentUtils.writeToFile(file, dest, progress, worker, source);
} catch (ReadContentInputStreamException ex) {
logger.log(Level.WARNING,
String.format("Error reading file '%s' (id=%d).",
file.getName(), file.getId()), ex); //NON-NLS
} catch (IOException ex) {
logger.log(Level.SEVERE,
"Trouble extracting slack file to " + dest.getAbsolutePath(), //NON-NLS
ex);
String.format("Error extracting slack file '%s' (id=%d) to '%s'.",
file.getName(), file.getId(), dest.getAbsolutePath()), ex); //NON-NLS
}
return null;
}
@ -381,15 +435,15 @@ public final class ContentUtils {
public Void visit(VirtualDirectory dir) {
return visitDir(dir);
}
@Override
public Void visit(LocalDirectory dir) {
return visitDir(dir);
}
private java.io.File getFsContentDest(Content fsc) {
private java.io.File getFsContentDest(Content content) {
String path = dest.getAbsolutePath() + java.io.File.separator
+ fsc.getName();
+ content.getName();
return new java.io.File(path);
}
@ -406,7 +460,7 @@ public final class ContentUtils {
int numProcessed = 0;
// recurse on children
for (Content child : dir.getChildren()) {
if (child instanceof AbstractFile){ //ensure the directory's artifact children are ignored
if (child instanceof AbstractFile) { //ensure the directory's artifact children are ignored
java.io.File childFile = getFsContentDest(child);
ExtractFscContentVisitor<T, V> childVisitor
= new ExtractFscContentVisitor<>(childFile, progress, worker, false);
@ -414,10 +468,10 @@ public final class ContentUtils {
// will have a progress and worker, and will keep track
// of the progress bar's progress
if (worker != null && worker.isCancelled()) {
break;
break;
}
if (progress != null && source) {
progress.progress(child.getName(), numProcessed);
progress.progress(child.getName(), numProcessed);
}
child.accept(childVisitor);
numProcessed++;
@ -447,5 +501,5 @@ public final class ContentUtils {
public static boolean shouldDisplayTimesInLocalTime() {
return displayTimesInLocalTime;
}
}
}

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Copyright 2014-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -37,10 +37,14 @@ import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
class CallLogAnalyzer {
/**
* Look for call logs and allow resulting blackboard artifacts to be generated.
*/
final class CallLogAnalyzer {
private Connection connection = null;
private ResultSet resultSet = null;
@ -48,10 +52,15 @@ class CallLogAnalyzer {
private String dbPath = "";
private long fileId = 0;
private java.io.File jFile = null;
private String moduleName = iOSModuleFactory.getModuleName();
private final String moduleName = iOSModuleFactory.getModuleName();
private static final Logger logger = Logger.getLogger(CallLogAnalyzer.class.getName());
private Blackboard blackboard;
/**
* Find call logs given an ingest job context and index the results.
*
* @param context The ingest job context.
*/
public void findCallLogs(IngestJobContext context) {
blackboard = Case.getCurrentCase().getServices().getBlackboard();
List<AbstractFile> absFiles;
@ -61,15 +70,17 @@ class CallLogAnalyzer {
if (absFiles.isEmpty()) {
return;
}
for (AbstractFile AF : absFiles) {
for (AbstractFile file : absFiles) {
try {
jFile = new java.io.File(Case.getCurrentCase().getTempDirectory(), AF.getName().replaceAll("[<>%|\"/:*\\\\]", ""));
ContentUtils.writeToFile(AF, jFile, context::dataSourceIngestIsCancelled);
jFile = new java.io.File(Case.getCurrentCase().getTempDirectory(), file.getName().replaceAll("[<>%|\"/:*\\\\]", ""));
dbPath = jFile.toString(); //path of file as string
fileId = AF.getId();
fileId = file.getId();
ContentUtils.writeToFile(file, jFile, context::dataSourceIngestIsCancelled);
findCallLogsInDB(dbPath, fileId);
} catch (Exception e) {
logger.log(Level.SEVERE, "Error parsing Call logs", e); //NON-NLS
} catch (ReadContentInputStreamException ex) {
logger.log(Level.WARNING, String.format("Error reading content from file '%s' (id=%d).", file.getName(), fileId), ex); //NON-NLS
} catch (Exception ex) {
logger.log(Level.SEVERE, String.format("Error writing content from file '%s' (id=%d) to '%s'.", file.getName(), fileId, dbPath), ex); //NON-NLS
}
}
} catch (TskCoreException e) {
@ -77,8 +88,14 @@ class CallLogAnalyzer {
}
}
/**
* Index results for call logs found in the database.
*
* @param DatabasePath The path to the database.
* @param fileId The ID of the file associated with artifacts.
*/
@Messages({"CallLogAnalyzer.indexError.message=Failed to index call log artifact for keyword search."})
private void findCallLogsInDB(String DatabasePath, long fId) {
private void findCallLogsInDB(String DatabasePath, long fileId) {
if (DatabasePath == null || DatabasePath.isEmpty()) {
return;
}
@ -93,9 +110,9 @@ class CallLogAnalyzer {
Case currentCase = Case.getCurrentCase();
SleuthkitCase skCase = currentCase.getSleuthkitCase();
try {
AbstractFile f = skCase.getAbstractFileById(fId);
if (f == null) {
logger.log(Level.SEVERE, "Error getting abstract file " + fId); //NON-NLS
AbstractFile file = skCase.getAbstractFileById(fileId);
if (file == null) {
logger.log(Level.SEVERE, "Error getting abstract file {0}", fileId); //NON-NLS
return;
}
@ -117,7 +134,7 @@ class CallLogAnalyzer {
date = resultSet.getString("date"); //NON-NLS
type = resultSet.getString("type"); //NON-NLS
bba = f.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG); //create a call log and then add attributes from result set.
bba = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG); //create a call log and then add attributes from result set.
Collection<BlackboardAttribute> attributes = new ArrayList<>();
if (type.equalsIgnoreCase("outgoing")) { //NON-NLS
attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO, moduleName, number));

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Copyright 2014-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -43,10 +43,14 @@ import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.ReadContentInputStream;
import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
class ContactAnalyzer {
/**
* Look for call logs and allow resulting blackboard artifacts to be generated.
*/
final class ContactAnalyzer {
private Connection connection = null;
private ResultSet resultSet = null;
@ -54,10 +58,15 @@ class ContactAnalyzer {
private String dbPath = "";
private long fileId = 0;
private java.io.File jFile = null;
private String moduleName = iOSModuleFactory.getModuleName();
private final String moduleName = iOSModuleFactory.getModuleName();
private static final Logger logger = Logger.getLogger(ContactAnalyzer.class.getName());
private Blackboard blackboard;
/**
* Find contacts given an ingest job context and index the results.
*
* @param context The ingest job context.
*/
public void findContacts(IngestJobContext context) {
blackboard = Case.getCurrentCase().getServices().getBlackboard();
@ -68,18 +77,16 @@ class ContactAnalyzer {
if (absFiles.isEmpty()) {
return;
}
for (AbstractFile AF : absFiles) {
for (AbstractFile file : absFiles) {
try {
jFile = new java.io.File(Case.getCurrentCase().getTempDirectory(), AF.getName().replaceAll("[<>%|\"/:*\\\\]", ""));
//jFile = new java.io.File(Case.getCurrentCase().getTempDirectory(), i+".txt");
ContentUtils.writeToFile(AF, jFile, context::dataSourceIngestIsCancelled);
//copyFileUsingStreams(AF,jFile);
//copyFileUsingStream(AF,jFile);
jFile = new java.io.File(Case.getCurrentCase().getTempDirectory(), file.getName().replaceAll("[<>%|\"/:*\\\\]", ""));
dbPath = jFile.toString(); //path of file as string
fileId = AF.getId();
//findContactsInDB(dbPath, fileId);
} catch (Exception e) {
logger.log(Level.SEVERE, "Error parsing Contacts", e); //NON-NLS
fileId = file.getId();
ContentUtils.writeToFile(file, jFile, context::dataSourceIngestIsCancelled);
} catch (ReadContentInputStreamException ex) {
logger.log(Level.WARNING, String.format("Error reading content from file '%s' (id=%d).", file.getName(), fileId), ex); //NON-NLS
} catch (Exception ex) {
logger.log(Level.SEVERE, String.format("Error writing content from file '%s' (id=%d) to '%s'.", file.getName(), fileId, dbPath), ex); //NON-NLS
}
}
} catch (TskCoreException e) {
@ -88,14 +95,14 @@ class ContactAnalyzer {
}
/**
* Create blackboard artifacts and index results for call logs found in the
* database.
*
* @param DatabasePath
* @param fId Will create artifact from a database given by the
* path The fileId will be the Abstract file associated
* with the artifacts
* @param DatabasePath The path to the database.
* @param fileId The ID of the file associated with artifacts.
*/
@Messages({"ContactAnalyzer.indexError.message=Failed to index contact artifact for keyword search."})
private void findContactsInDB(String DatabasePath, long fId) {
private void findContactsInDB(String DatabasePath, long fileId) {
if (DatabasePath == null || DatabasePath.isEmpty()) {
return;
}
@ -110,9 +117,9 @@ class ContactAnalyzer {
Case currentCase = Case.getCurrentCase();
SleuthkitCase skCase = currentCase.getSleuthkitCase();
try {
AbstractFile f = skCase.getAbstractFileById(fId);
if (f == null) {
logger.log(Level.SEVERE, "Error getting abstract file " + fId); //NON-NLS
AbstractFile file = skCase.getAbstractFileById(fileId);
if (file == null) {
logger.log(Level.SEVERE, "Error getting abstract file {0}", fileId); //NON-NLS
return;
}
@ -129,7 +136,7 @@ class ContactAnalyzer {
+ "ORDER BY name_raw_contact.display_name ASC;"); //NON-NLS
BlackboardArtifact bba;
bba = f.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT);
bba = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT);
Collection<BlackboardAttribute> attributes = new ArrayList<>();
String name;
String oldName = "";
@ -148,7 +155,7 @@ class ContactAnalyzer {
attributes.add(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL, moduleName, data1));
}
oldName = name;
bba.addAttributes(attributes);
try {
// index the artifact for keyword search
@ -157,7 +164,7 @@ class ContactAnalyzer {
logger.log(Level.SEVERE, "Unable to index blackboard artifact " + bba.getArtifactID(), ex); //NON-NLS
MessageNotifyUtil.Notify.error(
Bundle.ContactAnalyzer_indexError_message(), bba.getDisplayName());
}
}
}
} catch (Exception e) {

View File

@ -1,7 +1,7 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2014 Basis Technology Corp.
* Copyright 2014-2018 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
@ -38,9 +38,14 @@ import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.ReadContentInputStream;
import org.sleuthkit.datamodel.SleuthkitCase;
import org.sleuthkit.datamodel.TskCoreException;
/**
* Look for text messages and allow resulting blackboard artifacts to be
* generated.
*/
class TextMessageAnalyzer {
private Connection connection = null;
@ -50,10 +55,15 @@ class TextMessageAnalyzer {
private long fileId = 0;
private java.io.File jFile = null;
List<AbstractFile> absFiles;
private String moduleName = iOSModuleFactory.getModuleName();
private final String moduleName = iOSModuleFactory.getModuleName();
private static final Logger logger = Logger.getLogger(TextMessageAnalyzer.class.getName());
private Blackboard blackboard;
/**
* Find text messages given an ingest job context and index the results.
*
* @param context The ingest job context.
*/
void findTexts(IngestJobContext context) {
blackboard = Case.getCurrentCase().getServices().getBlackboard();
try {
@ -62,15 +72,17 @@ class TextMessageAnalyzer {
if (absFiles.isEmpty()) {
return;
}
for (AbstractFile AF : absFiles) {
for (AbstractFile file : absFiles) {
try {
jFile = new java.io.File(Case.getCurrentCase().getTempDirectory(), AF.getName().replaceAll("[<>%|\"/:*\\\\]", ""));
ContentUtils.writeToFile(AF, jFile, context::dataSourceIngestIsCancelled);
jFile = new java.io.File(Case.getCurrentCase().getTempDirectory(), file.getName().replaceAll("[<>%|\"/:*\\\\]", ""));
dbPath = jFile.toString(); //path of file as string
fileId = AF.getId();
fileId = file.getId();
ContentUtils.writeToFile(file, jFile, context::dataSourceIngestIsCancelled);
findTextsInDB(dbPath, fileId);
} catch (Exception e) {
logger.log(Level.SEVERE, "Error parsing text messages", e); //NON-NLS
} catch (ReadContentInputStream.ReadContentInputStreamException ex) {
logger.log(Level.WARNING, String.format("Error reading content from file '%s' (id=%d).", file.getName(), fileId), ex); //NON-NLS
} catch (Exception ex) {
logger.log(Level.SEVERE, String.format("Error writing content from file '%s' (id=%d) to '%s'.", file.getName(), fileId, dbPath), ex); //NON-NLS
}
}
} catch (TskCoreException e) {
@ -78,8 +90,15 @@ class TextMessageAnalyzer {
}
}
/**
* Create blackboard artifacts and index results for text messages found in
* the database.
*
* @param DatabasePath The path to the database.
* @param fileId The ID of the file associated with artifacts.
*/
@Messages({"TextMessageAnalyzer.indexError.message=Failed to index text message artifact for keyword search."})
private void findTextsInDB(String DatabasePath, long fId) {
private void findTextsInDB(String DatabasePath, long fileId) {
if (DatabasePath == null || DatabasePath.isEmpty()) {
return;
}
@ -94,9 +113,9 @@ class TextMessageAnalyzer {
Case currentCase = Case.getCurrentCase();
SleuthkitCase skCase = currentCase.getSleuthkitCase();
try {
AbstractFile f = skCase.getAbstractFileById(fId);
if (f == null) {
logger.log(Level.SEVERE, "Error getting abstract file " + fId); //NON-NLS
AbstractFile file = skCase.getAbstractFileById(fileId);
if (file == null) {
logger.log(Level.SEVERE, "Error getting abstract file {0}", fileId); //NON-NLS
return;
}
@ -117,7 +136,7 @@ class TextMessageAnalyzer {
subject = resultSet.getString("subject"); //NON-NLS
body = resultSet.getString("body"); //NON-NLS
bba = f.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE); //create Message artifact and then add attributes from result set.
bba = file.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE); //create Message artifact and then add attributes from result set.
Collection<BlackboardAttribute> attributes = new ArrayList<>();
// @@@ NEed to put into more specific TO or FROM
if (type.equals("1")) {

View File

@ -1,16 +1,16 @@
/*
*
* Autopsy Forensic Browser
*
*
* Copyright 2014-2018 Basis Technology Corp.
* contact: carrier <at> sleuthkit <dot> org
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -43,6 +43,7 @@ import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;
import org.jdom2.CDATA;
import org.openide.filesystems.FileUtil;
import org.sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
/**
* Generates a KML file based on geospatial information from the BlackBoard.
@ -67,7 +68,7 @@ class ReportKML implements GeneralReportModule {
PURPLE("style.kml#purpleFeature"),
WHITE("style.kml#whiteFeature"),
YELLOW("style.kml#yellowFeature");
private String color;
private final String color;
FeatureColor(String color) {
this.color = color;
@ -104,7 +105,7 @@ class ReportKML implements GeneralReportModule {
progressPanel.start();
progressPanel.updateStatusLabel(NbBundle.getMessage(this.getClass(), "ReportKML.progress.querying"));
String kmlFileFullPath = baseReportDir + REPORT_KML; //NON-NLS
currentCase = Case.getCurrentCase();
skCase = currentCase.getSleuthkitCase();
@ -197,6 +198,8 @@ class ReportKML implements GeneralReportModule {
*/
try {
for (BlackboardArtifact artifact : skCase.getBlackboardArtifacts(BlackboardArtifact.ARTIFACT_TYPE.TSK_METADATA_EXIF)) {
String fileName = "";
long fileId = 0;
try {
Long timestamp = getLong(artifact, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_CREATED);
String desc = getDescriptionFromArtifact(artifact, "EXIF Metadata With Locations"); //NON-NLS
@ -206,7 +209,9 @@ class ReportKML implements GeneralReportModule {
if (lat != null && lat != 0.0 && lon != null && lon != 0.0) {
AbstractFile abstractFile = artifact.getSleuthkitCase().getAbstractFileById(artifact.getObjectID());
Path path = null;
fileName = abstractFile.getName();
fileId = abstractFile.getId();
Path path;
copyFileUsingStream(abstractFile, Paths.get(baseReportDir, abstractFile.getName()).toFile());
try {
path = Paths.get(removeLeadingImgAndVol(abstractFile.getUniquePath()));
@ -219,6 +224,8 @@ class ReportKML implements GeneralReportModule {
}
gpsExifMetadataFolder.addContent(makePlacemarkWithPicture(abstractFile.getName(), FeatureColor.RED, desc, timestamp, point, path, formattedCoordinates));
}
} catch (ReadContentInputStreamException ex) {
logger.log(Level.WARNING, String.format("Error reading file '%s' (id=%d).", fileName, fileId), ex);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Could not extract photo information.", ex); //NON-NLS
result = ReportProgressPanel.ReportStatus.ERROR;
@ -404,9 +411,7 @@ class ReportKML implements GeneralReportModule {
BlackboardAttribute bba = artifact.getAttribute(new BlackboardAttribute.Type(type));
if (bba != null) {
Double value = bba.getValueDouble();
if (value != null) {
returnValue = value;
}
returnValue = value;
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting Double value: " + type.toString(), ex); //NON-NLS
@ -428,9 +433,7 @@ class ReportKML implements GeneralReportModule {
BlackboardAttribute bba = artifact.getAttribute(new BlackboardAttribute.Type(type));
if (bba != null) {
Long value = bba.getValueLong();
if (value != null) {
returnValue = value;
}
returnValue = value;
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting Long value: " + type.toString(), ex); //NON-NLS
@ -452,9 +455,7 @@ class ReportKML implements GeneralReportModule {
BlackboardAttribute bba = artifact.getAttribute(new BlackboardAttribute.Type(type));
if (bba != null) {
Integer value = bba.getValueInt();
if (value != null) {
returnValue = value;
}
returnValue = value;
}
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error getting Integer value: " + type.toString(), ex); //NON-NLS
@ -661,12 +662,12 @@ class ReportKML implements GeneralReportModule {
Element coordinates = new Element("coordinates", ns).addContent(longitude + "," + latitude + "," + altitude); //NON-NLS
if (altitude != 0) {
/*
Though we are including a non-zero altitude, clamp it to the
ground because inaccuracies from the GPS data can cause the terrain
to occlude points when zoomed in otherwise. Show the altitude, but
keep the point clamped to the ground. We may change this later for
flying GPS sensors.
/*
* Though we are including a non-zero altitude, clamp it to the
* ground because inaccuracies from the GPS data can cause the
* terrain to occlude points when zoomed in otherwise. Show the
* altitude, but keep the point clamped to the ground. We may change
* this later for flying GPS sensors.
*/
Element altitudeMode = new Element("altitudeMode", ns).addContent("clampToGround"); //NON-NLS
point.addContent(altitudeMode);
@ -811,9 +812,11 @@ class ReportKML implements GeneralReportModule {
* @param inputFile The input AbstractFile to copy
* @param outputFile the output file
*
* @throws IOException
* @throws ReadContentInputStreamException When a read error occurs.
* @throws IOException When a general file exception
* occurs.
*/
private void copyFileUsingStream(AbstractFile inputFile, File outputFile) throws IOException {
private void copyFileUsingStream(AbstractFile inputFile, File outputFile) throws ReadContentInputStreamException, IOException {
byte[] buffer = new byte[65536];
int length;
outputFile.createNewFile();