Merged with latest

This commit is contained in:
Eugene Livis 2015-07-23 10:30:30 -04:00
commit 73f49ccc73
8 changed files with 121 additions and 182 deletions

View File

@ -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

View File

@ -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;
}
} }

View File

@ -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.
*/ */

View File

@ -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) {

View File

@ -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

View 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;
}
}

View File

@ -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

View File

@ -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);
}
}