mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-19 11:07:43 +00:00
Merged with latest
This commit is contained in:
commit
73f49ccc73
@ -256,3 +256,4 @@ CaseConverter.PotentiallyNonUniqueDatabaseName=Unclear if database name unique.
|
|||||||
CaseConverter.ConvertedToMultiUser=This case was converted to a Multi-user collaborative case on
|
CaseConverter.ConvertedToMultiUser=This case was converted to a Multi-user collaborative case on
|
||||||
CaseConverter.UnableToCopySourceImages=Unable to copy source images
|
CaseConverter.UnableToCopySourceImages=Unable to copy source images
|
||||||
CaseConverter.ConversionSuccessful=. Conversion successful:
|
CaseConverter.ConversionSuccessful=. Conversion successful:
|
||||||
|
CaseConverter.DeletingCase=Deleting original case folder
|
||||||
|
@ -61,6 +61,7 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||||
import org.sleuthkit.autopsy.coreutils.Version;
|
import org.sleuthkit.autopsy.coreutils.Version;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
||||||
@ -1049,7 +1050,7 @@ public class Case {
|
|||||||
public String getModuleOutputDirectoryRelativePath() {
|
public String getModuleOutputDirectoryRelativePath() {
|
||||||
Path thePath;
|
Path thePath;
|
||||||
if (getCaseType() == CaseType.MULTI_USER_CASE) {
|
if (getCaseType() == CaseType.MULTI_USER_CASE) {
|
||||||
thePath = Paths.get(getLocalHostName(), MODULE_FOLDER);
|
thePath = Paths.get(NetworkUtils.getLocalHostName(), MODULE_FOLDER);
|
||||||
} else {
|
} else {
|
||||||
thePath = Paths.get(MODULE_FOLDER);
|
thePath = Paths.get(MODULE_FOLDER);
|
||||||
}
|
}
|
||||||
@ -1062,7 +1063,7 @@ public class Case {
|
|||||||
* Get the host output directory path where modules should save their
|
* Get the host output directory path where modules should save their
|
||||||
* permanent data. If single-user case, the directory is a subdirectory of
|
* permanent data. If single-user case, the directory is a subdirectory of
|
||||||
* the case directory. If multi-user case, the directory is a subdirectory
|
* the case directory. If multi-user case, the directory is a subdirectory
|
||||||
* of HostName, which is a subdirectory of the case directory.
|
* of the hostName, which is a subdirectory of the case directory.
|
||||||
*
|
*
|
||||||
* @return the path to the host output directory
|
* @return the path to the host output directory
|
||||||
*/
|
*/
|
||||||
@ -1070,7 +1071,7 @@ public class Case {
|
|||||||
String caseDirectory = getCaseDirectory();
|
String caseDirectory = getCaseDirectory();
|
||||||
Path hostPath;
|
Path hostPath;
|
||||||
if (caseType == CaseType.MULTI_USER_CASE) {
|
if (caseType == CaseType.MULTI_USER_CASE) {
|
||||||
hostPath = Paths.get(caseDirectory, getLocalHostName());
|
hostPath = Paths.get(caseDirectory, NetworkUtils.getLocalHostName());
|
||||||
} else {
|
} else {
|
||||||
hostPath = Paths.get(caseDirectory);
|
hostPath = Paths.get(caseDirectory);
|
||||||
}
|
}
|
||||||
@ -1386,7 +1387,7 @@ public class Case {
|
|||||||
String hostClause = "";
|
String hostClause = "";
|
||||||
|
|
||||||
if (caseType == CaseType.MULTI_USER_CASE) {
|
if (caseType == CaseType.MULTI_USER_CASE) {
|
||||||
hostClause = File.separator + getLocalHostName();
|
hostClause = File.separator + NetworkUtils.getLocalHostName();
|
||||||
}
|
}
|
||||||
result = result && (new File(caseDir + hostClause + File.separator + EXPORT_FOLDER)).mkdirs()
|
result = result && (new File(caseDir + hostClause + File.separator + EXPORT_FOLDER)).mkdirs()
|
||||||
&& (new File(caseDir + hostClause + File.separator + LOG_FOLDER)).mkdirs()
|
&& (new File(caseDir + hostClause + File.separator + LOG_FOLDER)).mkdirs()
|
||||||
@ -1618,24 +1619,5 @@ public class Case {
|
|||||||
return hasData;
|
return hasData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the host name variable. Sometimes the network can be finicky, so the
|
|
||||||
* answer returned by getHostName() could throw an exception or be null.
|
|
||||||
* Have it read the environment variable if getHostName() is unsuccessful.
|
|
||||||
*/
|
|
||||||
public static String getLocalHostName() {
|
|
||||||
if (HostName == null || HostName.isEmpty()) {
|
|
||||||
try {
|
|
||||||
HostName = java.net.InetAddress.getLocalHost().getHostName();
|
|
||||||
} catch (UnknownHostException ex) {
|
|
||||||
// getLocalHost().getHostName() can fail in some situations.
|
|
||||||
// Use environment variable if so.
|
|
||||||
HostName = System.getenv("COMPUTERNAME");
|
|
||||||
}
|
|
||||||
if (HostName == null || HostName.isEmpty()) {
|
|
||||||
HostName = System.getenv("COMPUTERNAME");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return HostName;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.net.UnknownHostException;
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -42,6 +41,7 @@ import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceEvent;
|
|||||||
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceFailedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceFailedEvent;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
import org.sleuthkit.autopsy.events.AutopsyEventException;
|
||||||
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
|
||||||
@ -84,7 +84,7 @@ final class CollaborationMonitor {
|
|||||||
* Get the local host name so it can be used to identify the source of
|
* Get the local host name so it can be used to identify the source of
|
||||||
* collaboration tasks broadcast by this node.
|
* collaboration tasks broadcast by this node.
|
||||||
*/
|
*/
|
||||||
hostName = getHostName();
|
hostName = NetworkUtils.getLocalHostName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an event publisher that will be used to communicate with
|
* Create an event publisher that will be used to communicate with
|
||||||
@ -124,24 +124,6 @@ final class CollaborationMonitor {
|
|||||||
periodicTasksExecutor.scheduleAtFixedRate(new StaleTaskDetectionTask(), STALE_TASKS_DETECTION_INTERVAL_MINUTES, STALE_TASKS_DETECTION_INTERVAL_MINUTES, TimeUnit.MINUTES);
|
periodicTasksExecutor.scheduleAtFixedRate(new StaleTaskDetectionTask(), STALE_TASKS_DETECTION_INTERVAL_MINUTES, STALE_TASKS_DETECTION_INTERVAL_MINUTES, TimeUnit.MINUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines the name of the local host for use in describing local tasks.
|
|
||||||
*
|
|
||||||
* @return The host name of this Autopsy node.
|
|
||||||
*/
|
|
||||||
private static String getHostName() {
|
|
||||||
String name;
|
|
||||||
try {
|
|
||||||
name = java.net.InetAddress.getLocalHost().getHostName();
|
|
||||||
} catch (UnknownHostException notUsed) {
|
|
||||||
name = System.getenv("COMPUTERNAME");
|
|
||||||
}
|
|
||||||
if (name.isEmpty()) {
|
|
||||||
name = "Collaborator";
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shuts down this collaboration monitor.
|
* Shuts down this collaboration monitor.
|
||||||
*/
|
*/
|
||||||
|
@ -39,30 +39,25 @@ import java.text.SimpleDateFormat;
|
|||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.logging.Level;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.openide.util.Exceptions;
|
import org.openide.util.Exceptions;
|
||||||
import org.openide.util.NbBundle;
|
import org.openide.util.NbBundle;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
import org.sleuthkit.autopsy.casemodule.Case.CaseType;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
import org.sleuthkit.datamodel.CaseDbConnectionInfo;
|
import org.sleuthkit.datamodel.CaseDbConnectionInfo;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.NetworkUtils;
|
||||||
|
import org.sleuthkit.autopsy.coreutils.TimeStampUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert case(s) from single-user to multi-user. Recursively scans subfolders.
|
* Convert case(s) from single-user to multi-user. Recursively scans subfolders.
|
||||||
*/
|
*/
|
||||||
public class CaseConverter implements Runnable {
|
public class SingleUserCaseImporter implements Runnable {
|
||||||
|
|
||||||
private static final String AUTOPSY_DB_FILE = "autopsy.db"; //NON-NLS
|
private static final String AUTOPSY_DB_FILE = "autopsy.db"; //NON-NLS
|
||||||
private static final String DOTAUT = ".aut"; //NON-NLS
|
private static final String DOTAUT = ".aut"; //NON-NLS
|
||||||
private static final String CACHE_FOLDER = "Cache"; //NON-NLS
|
public static final String CASE_CONVERSION_LOG_FILE = "case_import_log.txt"; //NON-NLS
|
||||||
private static final String EXPORT_FOLDER = "Export"; //NON-NLS
|
|
||||||
private static final String LOG_FOLDER = "Log"; //NON-NLS
|
|
||||||
private static final String MODULE_FOLDER = "ModuleOutput"; //NON-NLS
|
|
||||||
private static final String REPORTS_FOLDER = "Reports"; //NON-NLS
|
|
||||||
private static final String TEMP_FOLDER = "Temp"; //NON-NLS
|
|
||||||
private static final String TIMELINE_FOLDER = "Timeline"; //NON-NLS
|
|
||||||
private final static String AIM_LOG_FILE_NAME = "auto_ingest_log.txt"; //NON-NLS
|
|
||||||
private final static String TIMELINE_FILE = "events.db"; //NON-NLS
|
|
||||||
public static final String CASE_CONVERSION_LOG_FILE = "case_conversion.txt"; //NON-NLS
|
|
||||||
private static final String logDateFormat = "yyyy/MM/dd HH:mm:ss"; //NON-NLS
|
private static final String logDateFormat = "yyyy/MM/dd HH:mm:ss"; //NON-NLS
|
||||||
private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(logDateFormat);
|
private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(logDateFormat);
|
||||||
private static final int MAX_DB_NAME_LENGTH = 63;
|
private static final int MAX_DB_NAME_LENGTH = 63;
|
||||||
@ -71,6 +66,8 @@ public class CaseConverter implements Runnable {
|
|||||||
private final String caseOutputFolder;
|
private final String caseOutputFolder;
|
||||||
private final String imageInputFolder;
|
private final String imageInputFolder;
|
||||||
private final String imageOutputFolder;
|
private final String imageOutputFolder;
|
||||||
|
private final boolean copyImages;
|
||||||
|
private final boolean deleteCase;
|
||||||
private final CaseDbConnectionInfo db;
|
private final CaseDbConnectionInfo db;
|
||||||
private final ConversionDoneCallback notifyOnComplete;
|
private final ConversionDoneCallback notifyOnComplete;
|
||||||
private PrintWriter writer;
|
private PrintWriter writer;
|
||||||
@ -86,14 +83,19 @@ public class CaseConverter implements Runnable {
|
|||||||
* @param imageInput the folder that holds the images to copy over
|
* @param imageInput the folder that holds the images to copy over
|
||||||
* @param imageOutput the destination folder for the images
|
* @param imageOutput the destination folder for the images
|
||||||
* @param database the connection information to talk to the PostgreSQL db
|
* @param database the connection information to talk to the PostgreSQL db
|
||||||
|
* @param copyImages true if images should be copied
|
||||||
|
* @param deleteCase true if the old version of the case should be deleted after import
|
||||||
* @param callback a callback from the calling panel for notification when
|
* @param callback a callback from the calling panel for notification when
|
||||||
* the conversion has completed. This is a Runnable on a different thread.
|
* the conversion has completed. This is a Runnable on a different thread.
|
||||||
*/
|
*/
|
||||||
public CaseConverter(String caseInput, String caseOutput, String imageInput, String imageOutput, CaseDbConnectionInfo database, ConversionDoneCallback callback) {
|
public SingleUserCaseImporter(String caseInput, String caseOutput, String imageInput, String imageOutput, CaseDbConnectionInfo database,
|
||||||
|
boolean copyImages, boolean deleteCase, ConversionDoneCallback callback) {
|
||||||
this.caseInputFolder = caseInput;
|
this.caseInputFolder = caseInput;
|
||||||
this.caseOutputFolder = caseOutput;
|
this.caseOutputFolder = caseOutput;
|
||||||
this.imageInputFolder = imageInput;
|
this.imageInputFolder = imageInput;
|
||||||
this.imageOutputFolder = imageOutput;
|
this.imageOutputFolder = imageOutput;
|
||||||
|
this.copyImages = copyImages;
|
||||||
|
this.deleteCase = deleteCase;
|
||||||
this.db = database;
|
this.db = database;
|
||||||
this.notifyOnComplete = callback;
|
this.notifyOnComplete = callback;
|
||||||
}
|
}
|
||||||
@ -115,7 +117,12 @@ public class CaseConverter implements Runnable {
|
|||||||
try {
|
try {
|
||||||
log("Beginning to convert " + input.toString() + " to " + caseOutputFolder + "\\" + oldCaseFolder); //NON-NLS
|
log("Beginning to convert " + input.toString() + " to " + caseOutputFolder + "\\" + oldCaseFolder); //NON-NLS
|
||||||
|
|
||||||
checkInput(input.toFile(), new File(imageInputFolder));
|
if(copyImages){
|
||||||
|
checkInput(input.toFile(), new File(imageInputFolder));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
checkInput(input.toFile(), null);
|
||||||
|
}
|
||||||
String oldCaseName = oldCaseFolder;
|
String oldCaseName = oldCaseFolder;
|
||||||
if (TimeStampUtils.endsWithTimeStamp(oldCaseName)) {
|
if (TimeStampUtils.endsWithTimeStamp(oldCaseName)) {
|
||||||
oldCaseName = oldCaseName.substring(0, oldCaseName.length() - TimeStampUtils.getTimeStampLength());
|
oldCaseName = oldCaseName.substring(0, oldCaseName.length() - TimeStampUtils.getTimeStampLength());
|
||||||
@ -127,7 +134,7 @@ public class CaseConverter implements Runnable {
|
|||||||
// read old xml config
|
// read old xml config
|
||||||
oldXmlCaseManagement.open(input.resolve(oldCaseName + DOTAUT).toString());
|
oldXmlCaseManagement.open(input.resolve(oldCaseName + DOTAUT).toString());
|
||||||
if (oldXmlCaseManagement.getCaseType() == CaseType.MULTI_USER_CASE) {
|
if (oldXmlCaseManagement.getCaseType() == CaseType.MULTI_USER_CASE) {
|
||||||
throw new Exception(NbBundle.getMessage(CaseConverter.class, "CaseConverter.AlreadyMultiUser"));
|
throw new Exception(NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.AlreadyMultiUser"));
|
||||||
}
|
}
|
||||||
|
|
||||||
String newCaseFolder = prepareOutput(caseOutputFolder, oldCaseFolder);
|
String newCaseFolder = prepareOutput(caseOutputFolder, oldCaseFolder);
|
||||||
@ -144,10 +151,12 @@ public class CaseConverter implements Runnable {
|
|||||||
|
|
||||||
File imageDestination = Paths.get(imageOutputFolder, caseName).toFile();
|
File imageDestination = Paths.get(imageOutputFolder, caseName).toFile();
|
||||||
|
|
||||||
copyResults(input, newCaseFolder); // Copy items to new hostname folder structure
|
copyResults(input, newCaseFolder, oldCaseName); // Copy items to new hostname folder structure
|
||||||
dbName = convertDb(dbName, input, newCaseFolder); // Change from SQLite to PostgreSQL
|
dbName = convertDb(dbName, input, newCaseFolder); // Change from SQLite to PostgreSQL
|
||||||
File imageSource = copyInputImages(imageInputFolder, oldCaseName, imageDestination); // Copy images over
|
if(copyImages){
|
||||||
fixPaths(imageSource.toString(), imageDestination.toString(), dbName); // Update paths in DB
|
File imageSource = copyInputImages(imageInputFolder, oldCaseName, imageDestination); // Copy images over
|
||||||
|
fixPaths(imageSource.toString(), imageDestination.toString(), dbName); // Update paths in DB
|
||||||
|
}
|
||||||
|
|
||||||
// create new XML config
|
// create new XML config
|
||||||
newXmlCaseManagement.create(Paths.get(caseOutputFolder, newCaseFolder).toString(),
|
newXmlCaseManagement.create(Paths.get(caseOutputFolder, newCaseFolder).toString(),
|
||||||
@ -159,8 +168,17 @@ public class CaseConverter implements Runnable {
|
|||||||
// Set created date. This calls writefile, no need to call it again
|
// Set created date. This calls writefile, no need to call it again
|
||||||
newXmlCaseManagement.setCreatedDate(oldXmlCaseManagement.getCreatedDate());
|
newXmlCaseManagement.setCreatedDate(oldXmlCaseManagement.getCreatedDate());
|
||||||
|
|
||||||
log(NbBundle.getMessage(CaseConverter.class, "CaseConverter.FinishedConverting")
|
// At this point the import has been finished successfully so we can delete the original case
|
||||||
+ input.toString() + NbBundle.getMessage(CaseConverter.class, "CaseConverter.To")
|
// (if requested). This *should* be fairly safe - at this point we know there was an autopsy file
|
||||||
|
// and database in the given directory so the user shouldn't be able to accidently blow away
|
||||||
|
// their C drive.
|
||||||
|
if(deleteCase){
|
||||||
|
log(NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.DeletingCase") + " " + input);
|
||||||
|
FileUtils.deleteDirectory(input.toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
log(NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.FinishedConverting")
|
||||||
|
+ input.toString() + NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.To")
|
||||||
+ caseOutputFolder + File.separatorChar + newCaseFolder);
|
+ caseOutputFolder + File.separatorChar + newCaseFolder);
|
||||||
} catch (Exception exp) {
|
} catch (Exception exp) {
|
||||||
/// clean up here
|
/// clean up here
|
||||||
@ -174,18 +192,18 @@ public class CaseConverter implements Runnable {
|
|||||||
* Ensure the input source has an autopsy.db and exists.
|
* Ensure the input source has an autopsy.db and exists.
|
||||||
*
|
*
|
||||||
* @param caseInput The folder containing a case to convert.
|
* @param caseInput The folder containing a case to convert.
|
||||||
* @param imageInput The folder containing the images to copy.
|
* @param imageInput The folder containing the images to copy or null if images are not being copied.
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private void checkInput(File caseInput, File imageInput) throws Exception {
|
private void checkInput(File caseInput, File imageInput) throws Exception {
|
||||||
if (false == caseInput.exists()) {
|
if (false == caseInput.exists()) {
|
||||||
throw new Exception(NbBundle.getMessage(CaseConverter.class, "CaseConverter.BadCaseSourceFolder"));
|
throw new Exception(NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.BadCaseSourceFolder"));
|
||||||
} else if (false == imageInput.exists()) {
|
} else if ((imageInput != null) && (false == imageInput.exists())) {
|
||||||
throw new Exception(NbBundle.getMessage(CaseConverter.class, "CaseConverter.BadImageSourceFolder"));
|
throw new Exception(NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.BadImageSourceFolder"));
|
||||||
}
|
}
|
||||||
Path path = Paths.get(caseInput.toString(), AUTOPSY_DB_FILE);
|
Path path = Paths.get(caseInput.toString(), AUTOPSY_DB_FILE);
|
||||||
if (false == path.toFile().exists()) {
|
if (false == path.toFile().exists()) {
|
||||||
throw new Exception(NbBundle.getMessage(CaseConverter.class, "CaseConverter.BadDatabaseFileName"));
|
throw new Exception(NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.BadDatabaseFileName"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +231,7 @@ public class CaseConverter implements Runnable {
|
|||||||
while (specificOutputFolder.exists()) {
|
while (specificOutputFolder.exists()) {
|
||||||
if (number == Integer.MAX_VALUE) {
|
if (number == Integer.MAX_VALUE) {
|
||||||
// oops. it never became unique. give up.
|
// oops. it never became unique. give up.
|
||||||
throw new Exception(NbBundle.getMessage(CaseConverter.class, "CaseConverter.NonUniqueOutputFolder") + caseFolder);
|
throw new Exception(NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.NonUniqueOutputFolder") + caseFolder);
|
||||||
}
|
}
|
||||||
temp = sanitizedCaseName + "_" + Integer.toString(number) + timeStamp; //NON-NLS
|
temp = sanitizedCaseName + "_" + Integer.toString(number) + timeStamp; //NON-NLS
|
||||||
specificOutputFolder = Paths.get(caseOutputFolder, temp).toFile();
|
specificOutputFolder = Paths.get(caseOutputFolder, temp).toFile();
|
||||||
@ -235,62 +253,24 @@ public class CaseConverter implements Runnable {
|
|||||||
* @param newCaseFolder deconflicted case name for the new multi-user case
|
* @param newCaseFolder deconflicted case name for the new multi-user case
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
private void copyResults(Path input, String newCaseFolder) throws IOException {
|
private void copyResults(Path input, String newCaseFolder, String caseName) throws IOException {
|
||||||
/// get hostname
|
/// get hostname
|
||||||
String hostName = Case.getLocalHostName();
|
String hostName = NetworkUtils.getLocalHostName();
|
||||||
Path source = input.resolve(CACHE_FOLDER);
|
|
||||||
Path destination;
|
|
||||||
|
|
||||||
if (source.toFile().exists()) {
|
if(input.toFile().exists()){
|
||||||
destination = Paths.get(caseOutputFolder, newCaseFolder, hostName, CACHE_FOLDER);
|
Path destination = Paths.get(caseOutputFolder, newCaseFolder, hostName);
|
||||||
FileUtils.copyDirectory(source.toFile(), destination.toFile());
|
FileUtils.copyDirectory(input.toFile(), destination.toFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
source = input.resolve(EXPORT_FOLDER);
|
// Remove the single-user .aut file and database
|
||||||
if (source.toFile().exists()) {
|
File oldDatabaseFile = Paths.get(caseOutputFolder, newCaseFolder, hostName, caseName + ".aut").toFile();
|
||||||
destination = Paths.get(caseOutputFolder, newCaseFolder, hostName, EXPORT_FOLDER);
|
if(oldDatabaseFile.exists()){
|
||||||
FileUtils.copyDirectory(source.toFile(), destination.toFile());
|
oldDatabaseFile.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
source = input.resolve(LOG_FOLDER);
|
File oldAutopsyFile = Paths.get(caseOutputFolder, newCaseFolder, hostName, "autopsy.db").toFile();
|
||||||
if (source.toFile().exists()) {
|
if(oldAutopsyFile.exists()){
|
||||||
destination = Paths.get(caseOutputFolder, newCaseFolder, hostName, LOG_FOLDER);
|
oldAutopsyFile.delete();
|
||||||
FileUtils.copyDirectory(source.toFile(), destination.toFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
source = input.resolve(MODULE_FOLDER);
|
|
||||||
if (source.toFile().exists()) {
|
|
||||||
destination = Paths.get(caseOutputFolder, newCaseFolder, hostName, MODULE_FOLDER);
|
|
||||||
FileUtils.copyDirectory(source.toFile(), destination.toFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
source = input.resolve(REPORTS_FOLDER);
|
|
||||||
if (source.toFile().exists()) {
|
|
||||||
destination = Paths.get(caseOutputFolder, newCaseFolder, hostName, REPORTS_FOLDER);
|
|
||||||
FileUtils.copyDirectory(source.toFile(), destination.toFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
source = input.resolve(TEMP_FOLDER);
|
|
||||||
if (source.toFile().exists()) {
|
|
||||||
destination = Paths.get(caseOutputFolder, newCaseFolder, hostName, TEMP_FOLDER);
|
|
||||||
FileUtils.copyDirectory(source.toFile(), destination.toFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
source = input.resolve(TIMELINE_FILE);
|
|
||||||
if (source.toFile().exists()) {
|
|
||||||
destination = Paths.get(caseOutputFolder, newCaseFolder, hostName, MODULE_FOLDER, TIMELINE_FOLDER, TIMELINE_FILE);
|
|
||||||
FileUtils.copyFile(source.toFile(), destination.toFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
source = input.resolve(AIM_LOG_FILE_NAME);
|
|
||||||
if (source.toFile().exists()) {
|
|
||||||
destination = Paths.get(caseOutputFolder, newCaseFolder, AIM_LOG_FILE_NAME);
|
|
||||||
FileUtils.copyFile(source.toFile(), destination.toFile());
|
|
||||||
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(destination.toString(), true)))) {
|
|
||||||
out.println(NbBundle.getMessage(CaseConverter.class, "CaseConverter.ConvertedToMultiUser") + new Date());
|
|
||||||
} catch (IOException e) {
|
|
||||||
// if unable to log it, no problem
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -904,6 +884,7 @@ public class CaseConverter implements Runnable {
|
|||||||
numberingPK = postgresqlConnection.createStatement();
|
numberingPK = postgresqlConnection.createStatement();
|
||||||
numberingPK.execute("ALTER SEQUENCE blackboard_artifact_tags_tag_id_seq RESTART WITH " + (biggestPK + 1)); //NON-NLS
|
numberingPK.execute("ALTER SEQUENCE blackboard_artifact_tags_tag_id_seq RESTART WITH " + (biggestPK + 1)); //NON-NLS
|
||||||
|
|
||||||
|
sqliteConnection.close();
|
||||||
postgresqlConnection.close();
|
postgresqlConnection.close();
|
||||||
|
|
||||||
return dbName;
|
return dbName;
|
||||||
@ -944,7 +925,7 @@ public class CaseConverter implements Runnable {
|
|||||||
// not unique. add numbers before dbName.
|
// not unique. add numbers before dbName.
|
||||||
if (number == Integer.MAX_VALUE) {
|
if (number == Integer.MAX_VALUE) {
|
||||||
// oops. it never became unique. give up.
|
// oops. it never became unique. give up.
|
||||||
throw new Exception(NbBundle.getMessage(CaseConverter.class, "CaseConverter.NonUniqueDatabaseName"));
|
throw new Exception(NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.NonUniqueDatabaseName"));
|
||||||
}
|
}
|
||||||
sanitizedDbName = "_" + Integer.toString(number) + "_" + baseDbName; //NON-NLS
|
sanitizedDbName = "_" + Integer.toString(number) + "_" + baseDbName; //NON-NLS
|
||||||
|
|
||||||
@ -959,7 +940,7 @@ public class CaseConverter implements Runnable {
|
|||||||
} else {
|
} else {
|
||||||
// Could be caused by database credentials, using user accounts that
|
// Could be caused by database credentials, using user accounts that
|
||||||
// can not check if other databases exist, so allow it to continue
|
// can not check if other databases exist, so allow it to continue
|
||||||
log(NbBundle.getMessage(CaseConverter.class, "CaseConverter.PotentiallyNonUniqueDatabaseName"));
|
log(NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.PotentiallyNonUniqueDatabaseName"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return sanitizedDbName;
|
return sanitizedDbName;
|
||||||
@ -992,7 +973,7 @@ public class CaseConverter implements Runnable {
|
|||||||
if (chosenInput != null && chosenInput.exists()) {
|
if (chosenInput != null && chosenInput.exists()) {
|
||||||
FileUtils.copyDirectory(chosenInput, output);
|
FileUtils.copyDirectory(chosenInput, output);
|
||||||
} else {
|
} else {
|
||||||
log(NbBundle.getMessage(CaseConverter.class, "CaseConverter.UnableToCopySourceImages"));
|
log(NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.UnableToCopySourceImages"));
|
||||||
}
|
}
|
||||||
return chosenInput;
|
return chosenInput;
|
||||||
}
|
}
|
||||||
@ -1005,7 +986,7 @@ public class CaseConverter implements Runnable {
|
|||||||
/// Fix paths in reports, tsk_files_path, and tsk_image_names tables
|
/// Fix paths in reports, tsk_files_path, and tsk_image_names tables
|
||||||
|
|
||||||
Connection postgresqlConnection = DriverManager.getConnection("jdbc:postgresql://" + db.getHost() + ":" + db.getPort() + "/" + dbName, db.getUserName(), db.getPassword()); //NON-NLS
|
Connection postgresqlConnection = DriverManager.getConnection("jdbc:postgresql://" + db.getHost() + ":" + db.getPort() + "/" + dbName, db.getUserName(), db.getPassword()); //NON-NLS
|
||||||
String hostName = Case.getLocalHostName();
|
String hostName = NetworkUtils.getLocalHostName();
|
||||||
|
|
||||||
// add hostname to reports
|
// add hostname to reports
|
||||||
Statement updateStatement = postgresqlConnection.createStatement();
|
Statement updateStatement = postgresqlConnection.createStatement();
|
||||||
@ -1157,7 +1138,7 @@ public class CaseConverter implements Runnable {
|
|||||||
writer = new PrintWriter(new BufferedWriter(new FileWriter(logFile, logFile.exists())), true);
|
writer = new PrintWriter(new BufferedWriter(new FileWriter(logFile, logFile.exists())), true);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
writer = null;
|
writer = null;
|
||||||
Exceptions.printStackTrace(ex);
|
Logger.getLogger(SingleUserCaseImporter.class.getName()).log(Level.WARNING, "Error opening log file " + logFile.toString(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1180,11 +1161,11 @@ public class CaseConverter implements Runnable {
|
|||||||
* not. True if all was successful, false otherwise.
|
* not. True if all was successful, false otherwise.
|
||||||
*/
|
*/
|
||||||
private void closeLog(boolean result) {
|
private void closeLog(boolean result) {
|
||||||
log(NbBundle.getMessage(CaseConverter.class, "CaseConverter.FinishedConverting")
|
log(NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.FinishedConverting")
|
||||||
+ caseInputFolder
|
+ caseInputFolder
|
||||||
+ NbBundle.getMessage(CaseConverter.class, "CaseConverter.To")
|
+ NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.To")
|
||||||
+ caseOutputFolder
|
+ caseOutputFolder
|
||||||
+ NbBundle.getMessage(CaseConverter.class, "CaseConverter.ConversionSuccessful")
|
+ NbBundle.getMessage(SingleUserCaseImporter.class, "CaseConverter.ConversionSuccessful")
|
||||||
+ result);
|
+ result);
|
||||||
|
|
||||||
if (writer != null) {
|
if (writer != null) {
|
@ -45,7 +45,7 @@ import org.xml.sax.SAXException;
|
|||||||
*
|
*
|
||||||
* @author jantonius
|
* @author jantonius
|
||||||
*/
|
*/
|
||||||
public class XMLCaseManagement implements CaseConfigFileInterface {
|
class XMLCaseManagement implements CaseConfigFileInterface {
|
||||||
|
|
||||||
final static String XSDFILE = "CaseSchema.xsd"; //NON-NLS
|
final static String XSDFILE = "CaseSchema.xsd"; //NON-NLS
|
||||||
final static String TOP_ROOT_NAME = "AutopsyCase"; //NON-NLS
|
final static String TOP_ROOT_NAME = "AutopsyCase"; //NON-NLS
|
||||||
|
43
Core/src/org/sleuthkit/autopsy/coreutils/NetworkUtils.java
Normal file
43
Core/src/org/sleuthkit/autopsy/coreutils/NetworkUtils.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2012-2015 Basis Technology Corp.
|
||||||
|
* Contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.coreutils;
|
||||||
|
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
|
||||||
|
public class NetworkUtils {
|
||||||
|
/**
|
||||||
|
* Set the host name variable. Sometimes the network can be finicky, so the
|
||||||
|
* answer returned by getHostName() could throw an exception or be null.
|
||||||
|
* Have it read the environment variable if getHostName() is unsuccessful.
|
||||||
|
*/
|
||||||
|
public static String getLocalHostName() {
|
||||||
|
String hostName = "";
|
||||||
|
try {
|
||||||
|
hostName = java.net.InetAddress.getLocalHost().getHostName();
|
||||||
|
} catch (UnknownHostException ex) {
|
||||||
|
// getLocalHost().getHostName() can fail in some situations.
|
||||||
|
// Use environment variable if so.
|
||||||
|
hostName = System.getenv("COMPUTERNAME");
|
||||||
|
}
|
||||||
|
if (hostName == null || hostName.isEmpty()) {
|
||||||
|
hostName = System.getenv("COMPUTERNAME");
|
||||||
|
}
|
||||||
|
return hostName;
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.casemodule;
|
package org.sleuthkit.autopsy.coreutils;
|
||||||
|
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@ -26,8 +26,8 @@ import java.util.regex.Pattern;
|
|||||||
*/
|
*/
|
||||||
public final class TimeStampUtils {
|
public final class TimeStampUtils {
|
||||||
|
|
||||||
// Pattern to identify whether case name contains a time stamp generated by Auto Ingest.
|
// Pattern to identify whether case name contains a generated time stamp.
|
||||||
// Sample case name created by auto-ingest: Case 1_2015_02_02_12_10_31 for case "Case 1"
|
// Sample case name with time stamp: Case 1_2015_02_02_12_10_31 for case "Case 1"
|
||||||
private static final Pattern timeStampPattern = Pattern.compile("\\d{4}_\\d{2}_\\d{2}_\\d{2}_\\d{2}_\\d{2}$");
|
private static final Pattern timeStampPattern = Pattern.compile("\\d{4}_\\d{2}_\\d{2}_\\d{2}_\\d{2}_\\d{2}$");
|
||||||
private static final int LENGTH_OF_DATE_TIME_STAMP = 20; // length of the above time stamp
|
private static final int LENGTH_OF_DATE_TIME_STAMP = 20; // length of the above time stamp
|
||||||
|
|
@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
* Autopsy Forensic Browser
|
|
||||||
*
|
|
||||||
* Copyright 2011 Basis Technology Corp.
|
|
||||||
* Contact: carrier <at> sleuthkit <dot> org
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
package org.sleuthkit.autopsy.coreutils;
|
|
||||||
|
|
||||||
import java.text.DateFormat;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.logging.Formatter;
|
|
||||||
import java.util.logging.LogRecord;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Formatter to wrap another formatter and prepend a timestampe to each formatted string
|
|
||||||
* Not currently used.
|
|
||||||
*/
|
|
||||||
class TimestampingFormatter extends Formatter {
|
|
||||||
|
|
||||||
Formatter original;
|
|
||||||
DateFormat timestampFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, Locale.US);
|
|
||||||
String lineSeparator = System.getProperty("line.separator");
|
|
||||||
|
|
||||||
TimestampingFormatter(Formatter original) {
|
|
||||||
this.original = original;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String format(LogRecord record) {
|
|
||||||
long millis = record.getMillis();
|
|
||||||
String timestamp = timestampFormat.format(new Date(millis));
|
|
||||||
|
|
||||||
return timestamp + lineSeparator + original.format(record);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user