19package org.sleuthkit.autopsy.casemodule;
21import com.basistech.df.cybertriage.autopsy.CTIntegrationMissingDialog;
22import org.sleuthkit.autopsy.featureaccess.FeatureAccessUtils;
23import com.google.common.annotations.Beta;
24import com.google.common.eventbus.Subscribe;
25import com.google.common.util.concurrent.ThreadFactoryBuilder;
26import java.awt.Cursor;
27import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData;
29import java.awt.GraphicsEnvironment;
30import java.awt.event.ActionEvent;
31import java.awt.event.ActionListener;
32import java.beans.PropertyChangeListener;
33import java.beans.PropertyChangeSupport;
35import java.lang.reflect.InvocationTargetException;
36import java.nio.file.InvalidPathException;
37import java.nio.file.Path;
38import java.nio.file.Paths;
39import java.sql.Connection;
40import java.sql.DriverManager;
41import java.sql.ResultSet;
42import java.sql.SQLException;
43import java.sql.Statement;
44import java.text.SimpleDateFormat;
45import java.util.ArrayList;
46import java.util.Collection;
48import java.util.HashMap;
49import java.util.HashSet;
53import java.util.TimeZone;
55import java.util.concurrent.CancellationException;
56import java.util.concurrent.ExecutionException;
57import java.util.concurrent.ExecutorService;
58import java.util.concurrent.Executors;
59import java.util.concurrent.Future;
60import java.util.concurrent.ThreadFactory;
61import java.util.concurrent.TimeUnit;
62import java.util.logging.Level;
63import java.util.stream.Collectors;
64import java.util.stream.Stream;
65import javax.annotation.concurrent.GuardedBy;
66import javax.annotation.concurrent.ThreadSafe;
67import javax.swing.JOptionPane;
68import javax.swing.SwingUtilities;
69import org.apache.commons.lang3.ArrayUtils;
70import org.apache.commons.lang3.StringUtils;
71import org.openide.util.Lookup;
72import org.openide.util.NbBundle;
73import org.openide.util.NbBundle.Messages;
74import org.openide.util.actions.CallableSystemAction;
75import org.openide.windows.WindowManager;
76import org.sleuthkit.autopsy.actions.OpenOutputFolderAction;
77import org.sleuthkit.autopsy.appservices.AutopsyService;
78import org.sleuthkit.autopsy.appservices.AutopsyService.CaseContext;
79import org.sleuthkit.autopsy.casemodule.CaseMetadata.CaseMetadataException;
80import org.sleuthkit.autopsy.datasourcesummary.ui.DataSourceSummaryAction;
81import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceEvent;
82import org.sleuthkit.autopsy.casemodule.events.AddingDataSourceFailedEvent;
83import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent;
84import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagDeletedEvent;
85import org.sleuthkit.autopsy.casemodule.events.CommentChangedEvent;
86import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
87import org.sleuthkit.autopsy.casemodule.events.ContentTagDeletedEvent;
88import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
89import org.sleuthkit.autopsy.casemodule.events.DataSourceDeletedEvent;
90import org.sleuthkit.autopsy.casemodule.events.DataSourceNameChangedEvent;
91import org.sleuthkit.autopsy.casemodule.events.HostsAddedEvent;
92import org.sleuthkit.autopsy.casemodule.events.HostsAddedToPersonEvent;
93import org.sleuthkit.autopsy.casemodule.events.HostsUpdatedEvent;
94import org.sleuthkit.autopsy.casemodule.events.HostsDeletedEvent;
95import org.sleuthkit.autopsy.casemodule.events.HostsRemovedFromPersonEvent;
96import org.sleuthkit.autopsy.casemodule.events.OsAccountsAddedEvent;
97import org.sleuthkit.autopsy.casemodule.events.OsAccountsUpdatedEvent;
98import org.sleuthkit.autopsy.casemodule.events.OsAccountsDeletedEvent;
99import org.sleuthkit.autopsy.casemodule.events.OsAcctInstancesAddedEvent;
100import org.sleuthkit.autopsy.casemodule.events.PersonsAddedEvent;
101import org.sleuthkit.autopsy.casemodule.events.PersonsUpdatedEvent;
102import org.sleuthkit.autopsy.casemodule.events.PersonsDeletedEvent;
103import org.sleuthkit.autopsy.casemodule.events.ReportAddedEvent;
104import org.sleuthkit.autopsy.casemodule.events.TagNamesEvent.TagNamesAddedEvent;
105import org.sleuthkit.autopsy.casemodule.events.TagNamesEvent.TagNamesDeletedEvent;
106import org.sleuthkit.autopsy.casemodule.events.TagNamesEvent.TagNamesUpdatedEvent;
107import org.sleuthkit.autopsy.casemodule.events.TagSetsEvent.TagSetsAddedEvent;
108import org.sleuthkit.autopsy.casemodule.events.TagSetsEvent.TagSetsDeletedEvent;
109import org.sleuthkit.autopsy.casemodule.multiusercases.CaseNodeData.CaseNodeDataException;
110import org.sleuthkit.autopsy.casemodule.multiusercases.CoordinationServiceUtils;
111import org.sleuthkit.autopsy.casemodule.services.Services;
112import org.sleuthkit.autopsy.commonpropertiessearch.CommonAttributeSearchAction;
113import org.sleuthkit.autopsy.communications.OpenCommVisualizationToolAction;
114import org.sleuthkit.autopsy.coordinationservice.CoordinationService;
115import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CategoryNode;
116import org.sleuthkit.autopsy.coordinationservice.CoordinationService.CoordinationServiceException;
117import org.sleuthkit.autopsy.coordinationservice.CoordinationService.Lock;
118import org.sleuthkit.autopsy.core.RuntimeProperties;
119import org.sleuthkit.autopsy.core.UserPreferences;
120import org.sleuthkit.autopsy.core.UserPreferencesException;
121import org.sleuthkit.autopsy.corecomponentinterfaces.CoreComponentControl;
122import org.sleuthkit.autopsy.coreutils.DriveUtils;
123import org.sleuthkit.autopsy.coreutils.FileUtil;
124import org.sleuthkit.autopsy.coreutils.Logger;
125import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
126import org.sleuthkit.autopsy.coreutils.NetworkUtils;
127import org.sleuthkit.autopsy.coreutils.PlatformUtil;
128import org.sleuthkit.autopsy.coreutils.ThreadUtils;
129import org.sleuthkit.autopsy.coreutils.TimeZoneUtils;
130import org.sleuthkit.autopsy.coreutils.Version;
131import org.sleuthkit.autopsy.datamodel.hosts.OpenHostsAction;
132import org.sleuthkit.autopsy.directorytree.DirectoryTreeTopComponent;
133import org.sleuthkit.autopsy.events.AutopsyEvent;
134import org.sleuthkit.autopsy.events.AutopsyEventException;
135import org.sleuthkit.autopsy.events.AutopsyEventPublisher;
136import org.sleuthkit.autopsy.discovery.ui.OpenDiscoveryAction;
137import org.sleuthkit.autopsy.ingest.IngestJob;
138import org.sleuthkit.autopsy.ingest.IngestManager;
139import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchService;
140import org.sleuthkit.autopsy.keywordsearchservice.KeywordSearchServiceException;
141import org.sleuthkit.autopsy.machinesettings.UserMachinePreferences;
142import org.sleuthkit.autopsy.progress.LoggingProgressIndicator;
143import org.sleuthkit.autopsy.progress.ModalDialogProgressIndicator;
144import org.sleuthkit.autopsy.progress.ProgressIndicator;
145import org.sleuthkit.autopsy.timeline.OpenTimelineAction;
146import org.sleuthkit.autopsy.timeline.events.TimelineEventAddedEvent;
147import org.sleuthkit.datamodel.BlackboardArtifactTag;
148import org.sleuthkit.datamodel.CaseDbConnectionInfo;
149import org.sleuthkit.datamodel.ConcurrentDbAccessException;
150import org.sleuthkit.datamodel.Content;
151import org.sleuthkit.datamodel.ContentStreamProvider;
152import org.sleuthkit.datamodel.ContentTag;
153import org.sleuthkit.datamodel.DataSource;
154import org.sleuthkit.datamodel.FileSystem;
155import org.sleuthkit.datamodel.Image;
156import org.sleuthkit.datamodel.Report;
157import org.sleuthkit.datamodel.SleuthkitCase;
158import org.sleuthkit.datamodel.TimelineManager;
159import org.sleuthkit.datamodel.SleuthkitCaseAdminUtil;
160import org.sleuthkit.datamodel.TskCoreException;
161import org.sleuthkit.datamodel.TskDataException;
162import org.sleuthkit.datamodel.TskEvent;
163import org.sleuthkit.datamodel.TskUnsupportedSchemaVersionException;
191 = Executors.newSingleThreadExecutor(
new ThreadFactoryBuilder().setNameFormat(
"case-open-file-systems-%d").build());
211 if (!GraphicsEnvironment.isHeadless()) {
212 WindowManager.getDefault().invokeWhenUIReady(() -> {
213 mainFrame = WindowManager.getDefault().getMainWindow();
238 if (
typeName.equalsIgnoreCase(c.toString())) {
262 "Case_caseType_singleUser=Single-user case",
263 "Case_caseType_multiUser=Multi-user case"
267 return Bundle.Case_caseType_singleUser();
269 return Bundle.Case_caseType_multiUser();
294 return (otherTypeName ==
null) ? false :
typeName.equals(otherTypeName);
549 }
catch (TskCoreException ex) {
550 logger.log(Level.SEVERE,
"Unable to retrieve the hasData status from the db", ex);
593 }
catch (TskCoreException ex) {
594 logger.log(Level.SEVERE,
"Unable to retrieve the hasData status from the db", ex);
677 .map(Events::toString)
678 .collect(Collectors.toSet()), listener);
689 .map(Events::toString)
690 .collect(Collectors.toSet()), listener);
713 eventTypes.forEach((
Events event) -> {
758 eventTypes.forEach((
Events event) -> {
772 return !(caseName.contains(
"\\") || caseName.contains(
"/") || caseName.contains(
":")
773 || caseName.contains(
"*") || caseName.contains(
"?") || caseName.contains(
"\"")
774 || caseName.contains(
"<") || caseName.contains(
">") || caseName.contains(
"|"));
826 "Case.exceptionMessage.emptyCaseName=Must specify a case name.",
827 "Case.exceptionMessage.emptyCaseDir=Must specify a case directory path."
833 if (caseDir.isEmpty()) {
853 "# {0} - exception message",
"Case.exceptionMessage.failedToReadMetadata=Failed to read case metadata:\n{0}.",
854 "Case.exceptionMessage.cannotOpenMultiUserCaseNoSettings=Multi-user settings are missing (see Tools, Options, Multi-user tab), cannot open a multi-user case."
861 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToReadMetadata(ex.getLocalizedMessage()), ex);
864 throw new CaseActionException(Bundle.Case_exceptionMessage_cannotOpenMultiUserCaseNoSettings());
892 throw new IllegalStateException(NbBundle.getMessage(
Case.class,
"Case.getCurCase.exception.noneOpen"), ex);
916 if (openCase ==
null) {
932 "# {0} - exception message",
"Case.closeException.couldNotCloseCase=Error closing case: {0}",
933 "Case.progressIndicatorTitle.closingCase=Closing Case"
943 logger.log(Level.INFO,
"Closing current case {0} ({1}) in {2}",
new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()});
945 logger.log(Level.INFO,
"Closed current case {0} ({1}) in {2}",
new Object[]{closedCase.getDisplayName(), closedCase.getName(), closedCase.getCaseDirectory()});
988 "Case.progressIndicatorTitle.deletingDataSource=Removing Data Source"
990 static void deleteDataSourceFromCurrentCase(Long dataSourceObjectID)
throws CaseActionException {
1007 Case theCase =
new Case(caseMetadata);
1008 theCase.doOpenCaseAction(Bundle.Case_progressIndicatorTitle_deletingDataSource(), theCase::deleteDataSource, CaseLockType.EXCLUSIVE,
false, dataSourceObjectID);
1029 "Case.progressIndicatorTitle.deletingCase=Deleting Case",
1030 "Case.exceptionMessage.cannotDeleteCurrentCase=Cannot delete current case, it must be closed first.",
1031 "# {0} - case display name",
"Case.exceptionMessage.deletionInterrupted=Deletion of the case {0} was cancelled."
1046 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
1053 }
catch (InterruptedException ex) {
1063 progressIndicator.
finish();
1078 "Case.progressIndicatorTitle.creatingCase=Creating Case",
1079 "Case.progressIndicatorTitle.openingCase=Opening Case",
1080 "Case.exceptionMessage.cannotLocateMainWindow=Cannot locate main application window"
1096 logger.log(Level.INFO,
"Opening {0} ({1}) in {2} as the current case",
new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()});
1097 String progressIndicatorTitle;
1100 progressIndicatorTitle = Bundle.Case_progressIndicatorTitle_creatingCase();
1101 openCaseAction = newCurrentCase::create;
1103 progressIndicatorTitle = Bundle.Case_progressIndicatorTitle_openingCase();
1104 openCaseAction = newCurrentCase::open;
1108 logger.log(Level.INFO,
"Opened {0} ({1}) in {2} as the current case",
new Object[]{newCurrentCase.getDisplayName(), newCurrentCase.getName(), newCurrentCase.getCaseDirectory()});
1135 String uniqueCaseName = caseDisplayName.replaceAll(
"[^\\p{ASCII}]",
"_");
1140 uniqueCaseName = uniqueCaseName.replaceAll(
"[\\p{Cntrl}]",
"_");
1145 uniqueCaseName = uniqueCaseName.replaceAll(
"[ /?:'\"\\\\]",
"_");
1150 uniqueCaseName = uniqueCaseName.toLowerCase();
1155 SimpleDateFormat dateFormat =
new SimpleDateFormat(
"yyyyMMdd_HHmmss");
1156 Date date =
new Date();
1157 uniqueCaseName = uniqueCaseName +
"_" + dateFormat.format(date);
1159 return uniqueCaseName;
1176 File caseDir =
new File(caseDirPath);
1177 if (caseDir.exists()) {
1178 if (caseDir.isFile()) {
1179 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.existNotDir", caseDirPath));
1180 }
else if (!caseDir.canRead() || !caseDir.canWrite()) {
1181 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.existCantRW", caseDirPath));
1188 if (!caseDir.mkdirs()) {
1189 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreate", caseDirPath));
1197 String hostPathComponent =
"";
1202 Path exportDir = Paths.get(caseDirPath, hostPathComponent,
EXPORT_FOLDER);
1203 if (!exportDir.toFile().mkdirs()) {
1204 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateCaseDir", exportDir));
1207 Path logsDir = Paths.get(caseDirPath, hostPathComponent,
LOG_FOLDER);
1208 if (!logsDir.toFile().mkdirs()) {
1209 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateCaseDir", logsDir));
1212 Path cacheDir = Paths.get(caseDirPath, hostPathComponent,
CACHE_FOLDER);
1213 if (!cacheDir.toFile().mkdirs()) {
1214 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateCaseDir", cacheDir));
1217 Path moduleOutputDir = Paths.get(caseDirPath, hostPathComponent,
MODULE_FOLDER);
1218 if (!moduleOutputDir.toFile().mkdirs()) {
1219 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateModDir", moduleOutputDir));
1222 Path reportsDir = Paths.get(caseDirPath, hostPathComponent,
REPORTS_FOLDER);
1223 if (!reportsDir.toFile().mkdirs()) {
1224 throw new CaseActionException(NbBundle.getMessage(
Case.class,
"Case.createCaseDir.exception.cantCreateReportsDir", reportsDir));
1235 static Map<Long, String> getImagePaths(SleuthkitCase db) {
1236 Map<Long, String> imgPaths =
new HashMap<>();
1238 Map<Long, List<String>> imgPathsList = db.getImagePaths();
1239 for (Map.Entry<Long, List<String>> entry : imgPathsList.entrySet()) {
1240 if (entry.getValue().size() > 0) {
1241 imgPaths.put(entry.getKey(), entry.getValue().get(0));
1244 }
catch (TskCoreException ex) {
1245 logger.log(Level.SEVERE,
"Error getting image paths", ex);
1261 "Case.creationException.couldNotAcquireResourcesLock=Failed to get lock on case resources"
1265 Path caseDirPath = Paths.get(caseDir);
1269 }
catch (InterruptedException ex) {
1272 throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock(), ex);
1295 String backupDbPath =
caseDb.getBackupDatabasePath();
1296 if (
null != backupDbPath) {
1297 JOptionPane.showMessageDialog(
1299 NbBundle.getMessage(
Case.class,
"Case.open.msgDlg.updated.msg", backupDbPath),
1300 NbBundle.getMessage(
Case.class,
"Case.open.msgDlg.updated.title"),
1301 JOptionPane.INFORMATION_MESSAGE);
1308 Map<Long, String> imgPaths = getImagePaths(
caseDb);
1309 for (Map.Entry<Long, String> entry : imgPaths.entrySet()) {
1310 long obj_id = entry.getKey();
1311 String path = entry.getValue();
1316 String hostName = StringUtils.defaultString(ds.getHost() ==
null ?
"" : ds.getHost().getName());
1321 SwingUtilities.invokeAndWait(
new Runnable() {
1324 int response = JOptionPane.showConfirmDialog(
1326 NbBundle.getMessage(
Case.class,
"Case.checkImgExist.confDlg.doesntExist.msg", hostName, path),
1327 NbBundle.getMessage(
Case.class,
"Case.checkImgExist.confDlg.doesntExist.title"),
1328 JOptionPane.YES_NO_OPTION);
1329 if (response == JOptionPane.YES_OPTION) {
1330 MissingImageDialog.makeDialog(obj_id,
caseDb);
1332 logger.log(Level.SEVERE,
"User proceeding with missing image files");
1338 }
catch (InterruptedException | InvocationTargetException | TskCoreException | TskDataException ex) {
1339 logger.log(Level.SEVERE,
"Failed to show missing image confirmation dialog", ex);
1350 CallableSystemAction.get(CaseDetailsAction.class).setEnabled(
true);
1367 SwingUtilities.invokeLater(() -> {
1376 mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
1383 mainFrame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
1399 SwingUtilities.invokeLater(() -> {
1409 CallableSystemAction.get(
AddImageAction.class).setEnabled(
false);
1412 CallableSystemAction.get(CaseDetailsAction.class).setEnabled(
false);
1414 CallableSystemAction.get(CaseDeleteAction.class).setEnabled(
false);
1487 return metadata.getCaseDisplayName();
1514 return metadata.getExaminerPhone();
1523 return metadata.getExaminerEmail();
1541 return metadata.getCaseDirectory();
1558 hostPath = Paths.get(caseDirectory);
1560 if (!hostPath.toFile().exists()) {
1561 hostPath.toFile().mkdirs();
1563 return hostPath.toString();
1570 return Paths.get(System.getProperty(
"java.io.tmpdir"),
APP_NAME,
getName());
1582 Path basePath =
null;
1587 basePath = (StringUtils.isBlank(customDirectory))
1609 File caseTempDir = basePath
1610 .resolve(caseRelPath)
1614 if (!caseTempDir.exists()) {
1615 caseTempDir.mkdirs();
1618 return caseTempDir.getAbsolutePath();
1691 return path.subpath(path.getNameCount() - 2, path.getNameCount()).toString();
1693 return path.subpath(path.getNameCount() - 1, path.getNameCount()).toString();
1707 return caseDb.getRootObjects();
1716 Set<TimeZone> timezones =
new HashSet<>();
1717 String query =
"SELECT time_zone FROM data_source_info";
1718 try (SleuthkitCase.CaseDbQuery dbQuery =
caseDb.executeQuery(query)) {
1719 ResultSet timeZoneSet = dbQuery.getResultSet();
1720 while (timeZoneSet.next()) {
1721 String timeZone = timeZoneSet.getString(
"time_zone");
1722 if (timeZone !=
null && !timeZone.isEmpty()) {
1723 timezones.add(TimeZone.getTimeZone(timeZone));
1726 }
catch (TskCoreException | SQLException ex) {
1727 logger.log(Level.SEVERE,
"Error getting data source time zones", ex);
1879 logger.log(Level.WARNING,
"Unable to send notifcation regarding comment change due to no current case being open", ex);
1929 public void addReport(String localPath, String srcModuleName, String reportName)
throws TskCoreException {
1930 addReport(localPath, srcModuleName, reportName,
null);
1947 public Report
addReport(String localPath, String srcModuleName, String reportName, Content parent)
throws TskCoreException {
1948 String normalizedLocalPath;
1950 if (localPath.toLowerCase().contains(
"http:")) {
1951 normalizedLocalPath = localPath;
1953 normalizedLocalPath = Paths.get(localPath).normalize().toString();
1955 }
catch (InvalidPathException ex) {
1956 String errorMsg =
"Invalid local path provided: " + localPath;
1957 throw new TskCoreException(errorMsg, ex);
1961 Report
report = this.caseDb.addReport(normalizedLocalPath, srcModuleName, reportName, parent);
1975 return this.caseDb.getAllReports();
1986 public void deleteReports(Collection<? extends Report> reports)
throws TskCoreException {
1987 for (Report
report : reports) {
1988 this.caseDb.deleteReport(
report);
1993 }
catch (TskCoreException ex) {
1994 logger.log(Level.SEVERE,
"Unable to retrieve the hasData status from the db", ex);
1997 for (Report
report : reports) {
2019 "Case.exceptionMessage.metadataUpdateError=Failed to update case metadata"
2021 void updateCaseDetails(CaseDetails caseDetails)
throws CaseActionException {
2024 metadata.setCaseDetails(caseDetails);
2025 }
catch (CaseMetadataException ex) {
2026 throw new CaseActionException(Bundle.Case_exceptionMessage_metadataUpdateError(), ex);
2032 CaseNodeData.writeCaseNodeData(nodeData);
2033 }
catch (CaseNodeDataException | InterruptedException ex) {
2034 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotUpdateCaseNodeData(ex.getLocalizedMessage()), ex);
2037 if (!oldCaseDetails.getCaseNumber().equals(caseDetails.
getCaseNumber())) {
2040 if (!oldCaseDetails.getExaminerName().equals(caseDetails.
getExaminerName())) {
2047 if (RuntimeProperties.runningWithGUI()) {
2048 SwingUtilities.invokeLater(() -> {
2051 RecentCases.getInstance().updateRecentCase(oldCaseDetails.getCaseDisplayName(),
metadata.getFilePath().toString(), caseDetails.
getCaseDisplayName(),
metadata.getFilePath().toString());
2052 }
catch (Exception ex) {
2053 logger.log(Level.SEVERE,
"Error updating case name in UI", ex);
2115 "Case.progressIndicatorCancelButton.label=Cancel",
2116 "Case.progressMessage.preparing=Preparing...",
2117 "Case.progressMessage.cancelling=Cancelling...",
2118 "Case.exceptionMessage.cancelled=Cancelled.",
2119 "# {0} - exception message",
"Case.exceptionMessage.execExceptionWrapperMessage={0}"
2129 if (allowCancellation) {
2133 progressIndicatorTitle,
2134 new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
2135 Bundle.Case_progressIndicatorCancelButton_label(),
2136 cancelButtonListener);
2140 progressIndicatorTitle);
2145 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
2157 caseAction.
execute(progressIndicator, additionalParams);
2161 if (
null == resourcesLock) {
2162 throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
2164 caseAction.
execute(progressIndicator, additionalParams);
2172 if (
null != cancelButtonListener) {
2181 }
catch (InterruptedException discarded) {
2185 if (
null != cancelButtonListener) {
2188 future.cancel(
true);
2191 }
catch (CancellationException discarded) {
2197 }
catch (ExecutionException ex) {
2202 throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getLocalizedMessage()), ex);
2204 progressIndicator.
finish();
2224 assert (additionalParams ==
null);
2254 }
catch (InterruptedException discarded) {
2256 close(progressIndicator);
2276 assert (additionalParams ==
null);
2307 }
catch (InterruptedException discarded) {
2309 close(progressIndicator);
2320 "Case_checkImagePaths_noPaths=The following images had no associated paths: {0}",
2321 "Case_checkImagePaths_exceptionOccurred=An exception occurred while checking if image paths are present"
2325 if (StringUtils.isNotBlank(
this.metadata.getContentProviderName())) {
2331 List<Image> noPathImages =
new ArrayList<>();
2332 List<Image> images = this.caseDb.getImages();
2333 for (Image img: images) {
2334 if (ArrayUtils.isEmpty(img.getPaths())) {
2335 noPathImages.add(img);
2339 if (!noPathImages.isEmpty()) {
2340 String imageListStr = noPathImages.stream().map(Image::getName).collect(Collectors.joining(
", "));
2343 }
catch (TskCoreException ex) {
2358 "# {0} - case",
"Case.openFileSystems.retrievingImages=Retrieving images for case: {0}...",
2359 "# {0} - image",
"Case.openFileSystems.openingImage=Opening all filesystems for image: {0}..."
2374 private static class BackgroundOpenFileSystemsTask
implements Runnable {
2392 caseName = (this.tskCase !=
null) ? this.tskCase.getDatabaseName() :
"";
2403 if (Thread.interrupted()) {
2404 throw new InterruptedException();
2416 return this.tskCase.getImages();
2417 }
catch (TskCoreException ex) {
2420 String.format(
"Could not obtain images while opening case: %s.",
caseName),
2436 private void openFileSystems(List<Image> images)
throws TskCoreException, InterruptedException {
2437 byte[] tempBuff =
new byte[512];
2439 for (Image image : images) {
2440 String imageStr = image.getName();
2444 Collection<FileSystem> fileSystems = this.tskCase.getImageFileSystems(image);
2446 for (FileSystem fileSystem : fileSystems) {
2447 fileSystem.read(tempBuff, 0, 512);
2459 if (images ==
null) {
2467 String.format(
"Skipping background load of file systems due to large number of images in case (%d)", images.size()));
2473 }
catch (InterruptedException ex) {
2476 String.format(
"Background operation opening all file systems in %s has been cancelled.",
caseName));
2477 }
catch (Exception ex) {
2479 logger.log(Level.WARNING,
"Error while opening file systems in background", ex);
2500 "Case.progressMessage.deletingDataSource=Removing the data source from the case...",
2501 "Case.exceptionMessage.dataSourceNotFound=The data source was not found.",
2502 "Case.exceptionMessage.errorDeletingDataSourceFromCaseDb=An error occurred while removing the data source from the case database.",
2503 "Case.exceptionMessage.errorDeletingDataSourceFromTextIndex=An error occurred while removing the data source from the text index.",})
2504 Void deleteDataSource(ProgressIndicator progressIndicator, Object additionalParams)
throws CaseActionException {
2505 assert (additionalParams instanceof Long);
2506 open(progressIndicator,
null);
2508 progressIndicator.progress(Bundle.Case_progressMessage_deletingDataSource());
2509 Long dataSourceObjectID = (Long) additionalParams;
2511 DataSource dataSource = this.caseDb.getDataSource(dataSourceObjectID);
2512 if (dataSource ==
null) {
2513 throw new CaseActionException(Bundle.Case_exceptionMessage_dataSourceNotFound());
2515 SleuthkitCaseAdminUtil.deleteDataSource(this.caseDb, dataSourceObjectID);
2516 }
catch (TskDataException | TskCoreException ex) {
2517 throw new CaseActionException(Bundle.Case_exceptionMessage_errorDeletingDataSourceFromCaseDb(), ex);
2521 }
catch (KeywordSearchServiceException ex) {
2522 throw new CaseActionException(Bundle.Case_exceptionMessage_errorDeletingDataSourceFromTextIndex(), ex);
2524 eventPublisher.publish(
new DataSourceDeletedEvent(dataSourceObjectID));
2527 close(progressIndicator);
2542 public SleuthkitCase
createPortableCase(String caseName, File portableCaseFolder)
throws TskCoreException {
2544 if (portableCaseFolder.exists()) {
2545 throw new TskCoreException(
"Portable case folder " + portableCaseFolder.toString() +
" already exists");
2547 if (!portableCaseFolder.mkdirs()) {
2548 throw new TskCoreException(
"Error creating portable case folder " + portableCaseFolder.toString());
2558 throw new TskCoreException(
"Error creating case metadata", ex);
2562 SleuthkitCase portableSleuthkitCase;
2564 portableSleuthkitCase = SleuthkitCase.newCase(dbFilePath);
2566 return portableSleuthkitCase;
2579 if (Thread.currentThread().isInterrupted()) {
2595 "Case.progressMessage.creatingCaseDirectory=Creating case directory..."
2602 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDirectory());
2603 if (
new File(
metadata.getCaseDirectory()).exists() ==
false) {
2604 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDirectory());
2616 "Case.progressMessage.switchingLogDirectory=Switching log directory..."
2619 progressIndicator.
progress(Bundle.Case_progressMessage_switchingLogDirectory());
2635 "Case.progressMessage.savingCaseMetadata=Saving case metadata to file...",
2636 "# {0} - exception message",
"Case.exceptionMessage.couldNotSaveCaseMetadata=Failed to save case metadata:\n{0}."
2639 progressIndicator.
progress(Bundle.Case_progressMessage_savingCaseMetadata());
2641 this.metadata.writeToFile();
2643 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotSaveCaseMetadata(ex.getLocalizedMessage()), ex);
2659 "Case.progressMessage.creatingCaseNodeData=Creating coordination service node data...",
2660 "# {0} - exception message",
"Case.exceptionMessage.couldNotCreateCaseNodeData=Failed to create coordination service node data:\n{0}."
2664 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseNodeData());
2668 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreateCaseNodeData(ex.getLocalizedMessage()), ex);
2685 "Case.progressMessage.updatingCaseNodeData=Updating coordination service node data...",
2686 "# {0} - exception message",
"Case.exceptionMessage.couldNotUpdateCaseNodeData=Failed to update coordination service node data:\n{0}."
2690 progressIndicator.
progress(Bundle.Case_progressMessage_updatingCaseNodeData());
2696 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotUpdateCaseNodeData(ex.getLocalizedMessage()), ex);
2707 "Case.progressMessage.clearingTempDirectory=Clearing case temp directory..."
2713 progressIndicator.
progress(Bundle.Case_progressMessage_clearingTempDirectory());
2729 "Case.progressMessage.creatingCaseDatabase=Creating case database...",
2730 "# {0} - exception message",
"Case.exceptionMessage.couldNotGetDbServerConnectionInfo=Failed to get case database server conneciton info:\n{0}.",
2731 "# {0} - exception message",
"Case.exceptionMessage.couldNotCreateCaseDatabase=Failed to create case database:\n{0}.",
2732 "# {0} - exception message",
"Case.exceptionMessage.couldNotSaveDbNameToMetadataFile=Failed to save case database name to case metadata file:\n{0}."
2735 progressIndicator.
progress(Bundle.Case_progressMessage_creatingCaseDatabase());
2754 }
catch (TskCoreException ex) {
2756 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreateCaseDatabase(ex.getLocalizedMessage()), ex);
2758 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotGetDbServerConnectionInfo(ex.getLocalizedMessage()), ex);
2760 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotSaveDbNameToMetadataFile(ex.getLocalizedMessage()), ex);
2776 "Case.progressMessage.openingCaseDatabase=Opening case database...",
2777 "# {0} - exception message",
"Case.exceptionMessage.couldNotOpenCaseDatabase=Failed to open case database:\n{0}.",
2778 "# {0} - exception message",
"Case.exceptionMessage.unsupportedSchemaVersionMessage=Unsupported case database schema version:\n{0}.",
2779 "Case.exceptionMessage.contentProviderCouldNotBeFound=Content provider was specified for the case but could not be loaded.",
2780 "Case.open.exception.multiUserCaseNotEnabled=Cannot open a multi-user case if multi-user cases are not enabled. See Tools, Options, Multi-User."
2783 progressIndicator.
progress(Bundle.Case_progressMessage_openingCaseDatabase());
2785 String databaseName =
metadata.getCaseDatabaseName();
2788 if (StringUtils.isNotBlank(
metadata.getContentProviderName()) && contentProvider ==
null) {
2792 throw new CaseActionException(Bundle.Case_exceptionMessage_contentProviderCouldNotBeFound());
2803 }
catch (TskUnsupportedSchemaVersionException ex) {
2804 throw new CaseActionException(Bundle.Case_exceptionMessage_unsupportedSchemaVersionMessage(ex.getLocalizedMessage()), ex);
2806 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotGetDbServerConnectionInfo(ex.getLocalizedMessage()), ex);
2807 }
catch (TskCoreException ex) {
2809 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotOpenCaseDatabase(ex.getLocalizedMessage()), ex);
2820 "# {0} - appplicationName",
2821 "Case_throwIfConcurrentDbAccessException_fileLock_concurrentAccessException=The case is open in {0}. Please close it before attempting to open it in Autopsy.",
2822 "Case_throwIfConcurrentDbAccessException_fileLock_concurrentAccessException_defaultApp=another application"
2825 ConcurrentDbAccessException concurrentEx =
null;
2826 Throwable curEx = ex;
2828 for (
int i = 0; i < 10; i++) {
2829 if (curEx ==
null) {
2831 }
else if (curEx instanceof ConcurrentDbAccessException foundEx) {
2832 concurrentEx = foundEx;
2835 curEx = curEx.getCause();
2839 if (concurrentEx !=
null) {
2840 throw new CaseActionException(Bundle.Case_throwIfConcurrentDbAccessException_fileLock_concurrentAccessException(
2841 StringUtils.defaultIfBlank(concurrentEx.getConflictingApplicationName(),
2842 Bundle.Case_throwIfConcurrentDbAccessException_fileLock_concurrentAccessException_defaultApp())
2858 Collection<? extends AutopsyContentProvider> customContentProviders = Lookup.getDefault().lookupAll(
AutopsyContentProvider.class);
2859 if (customContentProviders !=
null) {
2862 if (customProvider ==
null || !StringUtils.equalsIgnoreCase(providerName, customProvider.getName())) {
2866 ContentStreamProvider contentProvider = customProvider.load();
2867 if (contentProvider !=
null) {
2868 return contentProvider;
2884 "Case.progressMessage.openingCaseLevelServices=Opening case-level services...",})
2886 progressIndicator.
progress(Bundle.Case_progressMessage_openingCaseLevelServices());
2908 @NbBundle.Messages({
2909 "Case.progressMessage.openingApplicationServiceResources=Opening application service case resources...",
2910 "# {0} - service name",
"Case.serviceOpenCaseResourcesProgressIndicator.title={0} Opening Case Resources",
2911 "# {0} - service name",
"Case.serviceOpenCaseResourcesProgressIndicator.cancellingMessage=Cancelling opening case resources by {0}...",
2912 "# {0} - service name",
"Case.servicesException.notificationTitle={0} Error"
2923 progressIndicator.
progress(Bundle.Case_progressMessage_openingApplicationServiceResources());
2935 cancelButtonListener =
new CancelButtonListener(Bundle.Case_serviceOpenCaseResourcesProgressIndicator_cancellingMessage(service.getServiceName()));
2938 Bundle.Case_serviceOpenCaseResourcesProgressIndicator_title(service.getServiceName()),
2939 new String[]{Bundle.Case_progressIndicatorCancelButton_label()},
2940 Bundle.Case_progressIndicatorCancelButton_label(),
2941 cancelButtonListener);
2945 appServiceProgressIndicator.
start(Bundle.Case_progressMessage_preparing());
2947 String threadNameSuffix = service.getServiceName().replaceAll(
"[ ]",
"-");
2948 threadNameSuffix = threadNameSuffix.toLowerCase();
2950 ExecutorService executor = Executors.newSingleThreadExecutor(threadFactory);
2951 Future<Void> future = executor.submit(() -> {
2952 service.openCaseResources(context);
2955 if (
null != cancelButtonListener) {
2967 }
catch (InterruptedException discarded) {
2972 future.cancel(
true);
2973 }
catch (CancellationException discarded) {
2980 Case.logger.log(Level.WARNING, String.format(
"Opening of case resources by %s for %s (%s) in %s cancelled", service.getServiceName(),
getDisplayName(),
getName(),
getCaseDirectory(), service.getServiceName()));
2981 }
catch (ExecutionException ex) {
2988 Case.logger.log(Level.SEVERE, String.format(
"%s failed to open case resources for %s", service.getServiceName(),
this.getDisplayName()), ex);
2990 SwingUtilities.invokeLater(() -> {
3002 appServiceProgressIndicator.
finish();
3020 "Case.progressMessage.settingUpNetworkCommunications=Setting up network communications...",
3021 "# {0} - exception message",
"Case.exceptionMessage.couldNotOpenRemoteEventChannel=Failed to open remote events channel:\n{0}.",
3022 "# {0} - exception message",
"Case.exceptionMessage.couldNotCreatCollaborationMonitor=Failed to create collaboration monitor:\n{0}."
3026 progressIndicator.
progress(Bundle.Case_progressMessage_settingUpNetworkCommunications());
3032 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotOpenRemoteEventChannel(ex.getLocalizedMessage()), ex);
3033 }
catch (CollaborationMonitor.CollaborationMonitorException ex) {
3034 throw new CaseActionException(Bundle.Case_exceptionMessage_couldNotCreatCollaborationMonitor(ex.getLocalizedMessage()), ex);
3062 Bundle.Case_progressIndicatorTitle_closingCase());
3066 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
3077 close(progressIndicator);
3084 progressIndicator.
progress(Bundle.Case_progressMessage_preparing());
3086 if (
null == resourcesLock) {
3087 throw new CaseActionException(Bundle.Case_creationException_couldNotAcquireResourcesLock());
3089 close(progressIndicator);
3103 }
catch (InterruptedException | CancellationException unused) {
3110 }
catch (ExecutionException ex) {
3111 throw new CaseActionException(Bundle.Case_exceptionMessage_execExceptionWrapperMessage(ex.getCause().getMessage()), ex);
3114 progressIndicator.
finish();
3124 "Case.progressMessage.shuttingDownNetworkCommunications=Shutting down network communications...",
3125 "Case.progressMessage.closingApplicationServiceResources=Closing case-specific application service resources...",
3126 "Case.progressMessage.closingCaseDatabase=Closing case database..."
3136 progressIndicator.
progress(Bundle.Case_progressMessage_shuttingDownNetworkCommunications());
3147 progressIndicator.
progress(Bundle.Case_progressMessage_closingApplicationServiceResources());
3154 progressIndicator.
progress(Bundle.Case_progressMessage_closingCaseDatabase());
3167 progressIndicator.
progress(Bundle.Case_progressMessage_switchingLogDirectory());
3176 "# {0} - serviceName",
"Case.serviceCloseResourcesProgressIndicator.title={0} Closing Case Resources",
3177 "# {0} - service name",
"# {1} - exception message",
"Case.servicesException.serviceResourcesCloseError=Could not close case resources for {0} service: {1}"
3190 Bundle.Case_serviceCloseResourcesProgressIndicator_title(service.getServiceName()));
3194 progressIndicator.
start(Bundle.Case_progressMessage_preparing());
3196 String threadNameSuffix = service.getServiceName().replaceAll(
"[ ]",
"-");
3197 threadNameSuffix = threadNameSuffix.toLowerCase();
3199 ExecutorService executor = Executors.newSingleThreadExecutor(threadFactory);
3200 Future<Void> future = executor.submit(() -> {
3201 service.closeCaseResources(context);
3206 }
catch (InterruptedException ex) {
3207 Case.logger.log(Level.SEVERE, String.format(
"Unexpected interrupt while waiting on %s service to close case resources", service.getServiceName()), ex);
3208 }
catch (CancellationException ex) {
3209 Case.logger.log(Level.SEVERE, String.format(
"Unexpected cancellation while waiting on %s service to close case resources", service.getServiceName()), ex);
3210 }
catch (ExecutionException ex) {
3211 Case.logger.log(Level.SEVERE, String.format(
"%s service failed to open case resources", service.getServiceName()), ex);
3214 Bundle.Case_servicesException_notificationTitle(service.getServiceName()),
3215 Bundle.Case_servicesException_serviceResourcesCloseError(service.getServiceName(), ex.getLocalizedMessage())));
3219 progressIndicator.
finish();
3230 "Case.lockingException.couldNotAcquireSharedLock=Failed to get a shared lock on the case.",
3231 "Case.lockingException.couldNotAcquireExclusiveLock=Failed to get an exclusive lock on the case."
3234 String caseDir =
metadata.getCaseDirectory();
3244 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock());
3249 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireSharedLock(), ex);
3251 throw new CaseActionException(Bundle.Case_lockingException_couldNotAcquireExclusiveLock(), ex);
3278 if (!subDirectory.exists()) {
3279 subDirectory.mkdirs();
3281 return subDirectory.toString();
3297 "Case.exceptionMessage.errorsDeletingCase=Errors occured while deleting the case. See the application log for details."
3300 boolean errorsOccurred =
false;
3304 errorsOccurred =
true;
3305 logger.log(Level.WARNING, String.format(
"Failed to delete text index for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3311 errorsOccurred =
true;
3312 logger.log(Level.WARNING, String.format(
"Failed to delete case directory for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3317 if (errorsOccurred) {
3342 "Case.progressMessage.connectingToCoordSvc=Connecting to coordination service...",
3343 "# {0} - exception message",
"Case.exceptionMessage.failedToConnectToCoordSvc=Failed to connect to coordination service:\n{0}.",
3344 "Case.exceptionMessage.cannotGetLockToDeleteCase=Cannot delete case because it is open for another user or host.",
3345 "# {0} - exception message",
"Case.exceptionMessage.failedToLockCaseForDeletion=Failed to exclusively lock case for deletion:\n{0}.",
3346 "Case.progressMessage.fetchingCoordSvcNodeData=Fetching coordination service node data for the case...",
3347 "# {0} - exception message",
"Case.exceptionMessage.failedToFetchCoordSvcNodeData=Failed to fetch coordination service node data:\n{0}.",
3348 "Case.progressMessage.deletingResourcesCoordSvcNode=Deleting case resources coordination service node...",
3349 "Case.progressMessage.deletingCaseDirCoordSvcNode=Deleting case directory coordination service node..."
3352 progressIndicator.
progress(Bundle.Case_progressMessage_connectingToCoordSvc());
3357 logger.log(Level.SEVERE, String.format(
"Failed to connect to coordination service when attempting to delete %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3358 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToConnectToCoordSvc(ex.getLocalizedMessage()));
3362 boolean errorsOccurred =
false;
3364 if (dirLock ==
null) {
3365 logger.log(Level.INFO, String.format(
"Could not delete %s (%s) in %s because a case directory lock was held by another host",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()));
3369 progressIndicator.
progress(Bundle.Case_progressMessage_fetchingCoordSvcNodeData());
3373 logger.log(Level.SEVERE, String.format(
"Failed to get coordination service node data %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3374 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToFetchCoordSvcNodeData(ex.getLocalizedMessage()));
3379 progressIndicator.
progress(Bundle.Case_progressMessage_deletingResourcesCoordSvcNode());
3385 errorsOccurred =
true;
3386 logger.log(Level.WARNING, String.format(
"Error deleting the case resources coordination service node for the case at %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3388 }
catch (InterruptedException ex) {
3389 logger.log(Level.WARNING, String.format(
"Error deleting the case resources coordination service node for the case at %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3393 logger.log(Level.SEVERE, String.format(
"Error exclusively locking the case directory for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3394 throw new CaseActionException(Bundle.Case_exceptionMessage_failedToLockCaseForDeletion(ex.getLocalizedMessage()));
3397 if (!errorsOccurred) {
3398 progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDirCoordSvcNode());
3403 logger.log(Level.SEVERE, String.format(
"Error deleting the case directory lock node for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3404 errorsOccurred =
true;
3408 if (errorsOccurred) {
3439 boolean errorsOccurred =
false;
3446 errorsOccurred =
true;
3447 logger.log(Level.WARNING, String.format(
"Failed to delete the case database for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3449 errorsOccurred =
true;
3450 logger.log(Level.WARNING, String.format(
"Failed to delete the text index for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3452 errorsOccurred =
true;
3453 logger.log(Level.WARNING, String.format(
"Failed to delete the case directory for %s (%s) in %s",
metadata.getCaseDisplayName(),
metadata.getCaseName(),
metadata.getCaseDirectory()), ex);
3455 return errorsOccurred;
3479 "Case.progressMessage.deletingCaseDatabase=Deleting case database..."
3483 progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDatabase());
3486 String url =
"jdbc:postgresql://" + info.getHost() +
":" + info.getPort() +
"/postgres";
3487 Class.forName(
"org.postgresql.Driver");
3488 try (Connection connection = DriverManager.getConnection(url, info.getUserName(), info.getPassword()); Statement statement = connection.createStatement()) {
3489 String dbExistsQuery =
"SELECT 1 from pg_database WHERE datname = '" +
metadata.getCaseDatabaseName() +
"'";
3490 try (ResultSet queryResult = statement.executeQuery(dbExistsQuery)) {
3491 if (queryResult.next()) {
3492 String deleteCommand =
"DROP DATABASE \"" +
metadata.getCaseDatabaseName() +
"\"";
3493 statement.execute(deleteCommand);
3534 "Case.progressMessage.deletingTextIndex=Deleting text index..."
3537 progressIndicator.
progress(Bundle.Case_progressMessage_deletingTextIndex());
3541 searchService.deleteTextIndex(
metadata);
3577 "Case.progressMessage.deletingCaseDirectory=Deleting case directory..."
3580 progressIndicator.
progress(Bundle.Case_progressMessage_deletingCaseDirectory());
3594 "Case.progressMessage.removingCaseFromRecentCases=Removing case from Recent Cases menu..."
3598 progressIndicator.
progress(Bundle.Case_progressMessage_removingCaseFromRecentCases());
3599 SwingUtilities.invokeLater(() -> {
3600 RecentCases.getInstance().removeRecentCase(
metadata.getCaseDisplayName(),
metadata.getFilePath().toString());
3615 boolean isNodeNodeEx =
false;
3616 Throwable cause = ex.getCause();
3617 if (cause !=
null) {
3618 String causeMessage = cause.getMessage();
3621 return isNodeNodeEx;
3640 logger.log(Level.SEVERE, String.format(
"Error updating deleted item flag %s for %s (%s) in %s", flag.name(), caseNodeData.
getDisplayName(), caseNodeData.
getName(), caseNodeData.
getDirectory()), ex);
3674 String query =
"SELECT count(*) AS count FROM (SELECT * FROM data_source_info LIMIT 1)t";
3675 try (SleuthkitCase.CaseDbQuery dbQuery =
caseDb.executeQuery(query)) {
3676 ResultSet resultSet = dbQuery.getResultSet();
3677 if (resultSet.next()) {
3678 return resultSet.getLong(
"count") > 0;
3681 }
catch (SQLException ex) {
3682 logger.log(Level.SEVERE,
"Error accessing case database", ex);
3683 throw new TskCoreException(
"Error accessing case databse", ex);
3698 String query =
"SELECT SUM(cnt) total FROM "
3699 +
"(SELECT COUNT(*) AS cnt FROM "
3700 +
"(SELECT * FROM tsk_objects LIMIT 1)t "
3702 +
"SELECT COUNT(*) AS cnt FROM "
3703 +
"(SELECT * FROM tsk_hosts LIMIT 1)r) s";
3704 try (SleuthkitCase.CaseDbQuery dbQuery =
caseDb.executeQuery(query)) {
3705 ResultSet resultSet = dbQuery.getResultSet();
3706 if (resultSet.next()) {
3707 return resultSet.getLong(
"total") > 0;
3711 }
catch (SQLException ex) {
3712 logger.log(Level.SEVERE,
"Error accessing case database", ex);
3713 throw new TskCoreException(
"Error accessing case databse", ex);
3825 this.cancelRequested =
true;
3999 return new File(filePath).isFile();
4038 return "ModuleOutput";
4051 public static PropertyChangeSupport
4053 return new PropertyChangeSupport(
Case.class
4087 Image newDataSource =
caseDb.getImageById(imgId);
4089 return newDataSource;
4090 }
catch (TskCoreException ex) {
4091 throw new CaseActionException(NbBundle.getMessage(
this.getClass(),
"Case.addImg.exception.msg"), ex);
4118 public void deleteReports(Collection<? extends Report> reports,
boolean deleteFromDisk)
throws TskCoreException {
void showDialog(JComponent parentComp)
void openFileSystems(List< Image > images)
final long MAX_IMAGE_THRESHOLD
final ProgressIndicator progressIndicator
List< Image > getImages()
final SleuthkitCase tskCase
void publishOsAccountInstancesAddedEvent(TskEvent.OsAcctInstancesAddedTskEvent event)
void publishHostsAddedEvent(TskEvent.HostsAddedTskEvent event)
void publicTagNamesDeleted(TskEvent.TagNamesDeletedTskEvent event)
void publishOsAccountsUpdatedEvent(TskEvent.OsAccountsUpdatedTskEvent event)
void publishHostsAddedToPersonEvent(TskEvent.HostsAddedToPersonTskEvent event)
void publishTimelineEventAddedEvent(TimelineManager.TimelineEventAddedEvent event)
void publishPersonsDeletedEvent(TskEvent.PersonsDeletedTskEvent event)
void publishOsAccountsAddedEvent(TskEvent.OsAccountsAddedTskEvent event)
void publishHostsDeletedEvent(TskEvent.HostsDeletedTskEvent event)
void publishPersonsUpdatedEvent(TskEvent.PersonsUpdatedTskEvent event)
void publishPersonsAddedEvent(TskEvent.PersonsAddedTskEvent event)
void publicTagSetsDeleted(TskEvent.TagSetsDeletedTskEvent event)
void publicTagSetsAdded(TskEvent.TagSetsAddedTskEvent event)
void publishHostsUpdatedEvent(TskEvent.HostsUpdatedTskEvent event)
void publicTagNamesAdded(TskEvent.TagNamesAddedTskEvent event)
void publicTagNamesUpdated(TskEvent.TagNamesUpdatedTskEvent event)
void publisHostsRemovedFromPersonEvent(TskEvent.HostsRemovedFromPersonTskEvent event)
void publishOsAccountDeletedEvent(TskEvent.OsAccountsDeletedTskEvent event)
Thread newThread(Runnable task)
TaskThreadFactory(String threadName)
String getCaseDisplayName()
static boolean pathExists(String filePath)
static void openAsCurrentCase(String caseMetadataFilePath)
static final String EVENT_CHANNEL_NAME
static String getAutopsyVersion()
void notifyContentTagAdded(ContentTag newTag, List< ContentTag > deletedTagList)
String getExaminerEmail()
static void removeEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
String getOrCreateSubdirectory(String subDirectoryName)
static void closeCurrentCase()
static void deleteMultiUserCase(CaseMetadata metadata, ProgressIndicator progressIndicator)
void notifyFailedAddingDataSource(UUID addingDataSourceEventId)
static final int CASE_RESOURCES_LOCK_TIMEOUT_HOURS
static String displayNameToUniqueName(String caseDisplayName)
Set< TimeZone > getTimeZones()
Case(CaseMetadata caseMetaData)
String getLogDirectoryPath()
void doOpenCaseAction(String progressIndicatorTitle, CaseAction< ProgressIndicator, Object, Void > caseAction, CaseLockType caseLockType, boolean allowCancellation, Object additionalParams)
static void deleteMultiUserCaseDirectory(CaseNodeData caseNodeData, CaseMetadata metadata, ProgressIndicator progressIndicator, Logger logger)
Void open(ProgressIndicator progressIndicator, Object additionalParams)
void deleteReports(Collection<? extends Report > reports, boolean deleteFromDisk)
static final String MODULE_FOLDER
static volatile Case currentCase
volatile ExecutorService caseActionExecutor
static final String CASE_RESOURCES_THREAD_NAME
final CaseMetadata metadata
String getTextIndexName()
static void setDeletedItemFlag(CaseNodeData caseNodeData, CaseNodeData.DeletedFlags flag)
void openFileSystemsInBackground()
List< Content > getDataSources()
static void addEventSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
static void deleteMultiUserCaseTextIndex(CaseNodeData caseNodeData, CaseMetadata metadata, ProgressIndicator progressIndicator, Logger logger)
Case(CaseType caseType, String caseDir, CaseDetails caseDetails)
static Future<?> backgroundOpenFileSystemsFuture
volatile boolean hasDataSource
static void updateGUIForCaseOpened(Case newCurrentCase)
static void deleteFromRecentCases(CaseMetadata metadata, ProgressIndicator progressIndicator)
static final String TEMP_FOLDER
SleuthkitCase createPortableCase(String caseName, File portableCaseFolder)
SleuthkitCase getSleuthkitCase()
void updateCaseNodeData(ProgressIndicator progressIndicator)
static final String EXPORT_FOLDER
static void addEventSubscriber(String eventName, PropertyChangeListener subscriber)
List< Report > getAllReports()
static final String SINGLE_USER_CASE_DB_NAME
static void invokeStartupDialog()
static void removeEventSubscriber(String eventName, PropertyChangeListener subscriber)
static void openAsCurrentCase(Case newCurrentCase, boolean isNewCase)
static void open(String caseMetadataFilePath)
void createCaseDatabase(ProgressIndicator progressIndicator)
void notifyContentTagDeleted(ContentTag deletedTag)
String getExaminerPhone()
String getModuleOutputDirectoryRelativePath()
static final String CACHE_FOLDER
static String getNameForTitle()
static String getAppName()
String getModulesOutputDirAbsPath()
static void removePropertyChangeListener(PropertyChangeListener listener)
void notifyDataSourceNameChanged(Content dataSource, String newName)
void notifyAddingDataSource(UUID eventId)
void createCaseNodeData(ProgressIndicator progressIndicator)
static boolean isValidName(String caseName)
static void updateGUIForCaseClosed()
static void checkForCancellation()
Report addReport(String localPath, String srcModuleName, String reportName, Content parent)
static final String NO_NODE_ERROR_MSG_FRAGMENT
static final Object caseActionSerializationLock
static Case getCurrentCaseThrows()
static final String REPORTS_FOLDER
static ContentStreamProvider loadContentProvider(String providerName)
CaseMetadata getMetadata()
static void deleteCurrentCase()
void createCaseDirectoryIfDoesNotExist(ProgressIndicator progressIndicator)
void addReport(String localPath, String srcModuleName, String reportName)
static String getModulesOutputDirRelPath()
static void createCaseDirectory(String caseDirPath, CaseType caseType)
static Case getCurrentCase()
final SleuthkitEventListener sleuthkitEventListener
static final Logger logger
static void removeEventSubscriber(Set< String > eventNames, PropertyChangeListener subscriber)
String getCaseDirectory()
void openCommunicationChannels(ProgressIndicator progressIndicator)
static final AutopsyEventPublisher eventPublisher
static final ExecutorService openFileSystemsExecutor
static void createAsCurrentCase(String caseDir, String caseDisplayName, String caseNumber, String examiner, CaseType caseType)
static final String APP_NAME
static void addPropertyChangeListener(PropertyChangeListener listener)
static boolean existsCurrentCase()
static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner)
Set< TimeZone > getTimeZone()
static String convertTimeZone(String timeZoneId)
static final String LOG_FOLDER
void close(ProgressIndicator progressIndicator)
void updateDataParameters()
String getCacheDirectory()
static void deleteTextIndex(CaseMetadata metadata, ProgressIndicator progressIndicator)
void notifyBlackBoardArtifactTagAdded(BlackboardArtifactTag newTag, List< BlackboardArtifactTag > removedTagList)
static boolean isCaseOpen()
static final String CONFIG_FOLDER
String getConfigDirectory()
void notifyTagDefinitionChanged(String changedTagName)
static void deleteCase(CaseMetadata metadata)
static CoordinationService.Lock acquireCaseResourcesLock(String caseDir)
String getModuleDirectory()
static PropertyChangeSupport getPropertyChangeSupport()
static volatile Frame mainFrame
void deleteReports(Collection<? extends Report > reports)
void notifyCentralRepoCommentChanged(long contentId, String newComment)
static void create(String caseDir, String caseDisplayName, String caseNumber, String examiner, CaseType caseType)
static void deleteMultiUserCaseDatabase(CaseNodeData caseNodeData, CaseMetadata metadata, ProgressIndicator progressIndicator, Logger logger)
void notifyContentTagAdded(ContentTag newTag)
void openAppServiceCaseResources(ProgressIndicator progressIndicator, boolean isNewCase)
String getTempDirectory()
static final String CT_PROVIDER_PREFIX
static final String CASE_ACTION_THREAD_NAME
String getExportDirectory()
static final int CASE_LOCK_TIMEOUT_MINS
void throwIfConcurrentDbAccessException(Exception ex)
boolean dbHasDataSource()
void closeAppServiceCaseResources()
void saveCaseMetadataToFile(ProgressIndicator progressIndicator)
void acquireCaseLock(CaseLockType lockType)
String getReportDirectory()
static void deleteSingleUserCase(CaseMetadata metadata, ProgressIndicator progressIndicator)
static void createAsCurrentCase(CaseType caseType, String caseDir, CaseDetails caseDetails)
String getOutputDirectory()
static boolean isNoNodeException(CoordinationServiceException ex)
static boolean deleteMultiUserCase(CaseNodeData caseNodeData, CaseMetadata metadata, ProgressIndicator progressIndicator, Logger logger)
CollaborationMonitor collaborationMonitor
void notifyBlackBoardArtifactTagAdded(BlackboardArtifactTag newTag)
void switchLoggingToCaseLogsDirectory(ProgressIndicator progressIndicator)
void deleteTempfilesFromCaseDirectory(ProgressIndicator progressIndicator)
Image addImage(String imgPath, long imgId, String timeZone)
void notifyDataSourceAdded(Content dataSource, UUID addingDataSourceEventId)
Path getBaseSystemTempPath()
static void deleteCaseDirectory(CaseMetadata metadata, ProgressIndicator progressIndicator)
void notifyBlackBoardArtifactTagDeleted(BlackboardArtifactTag deletedTag)
void openCaseDataBase(ProgressIndicator progressIndicator)
void openCaseLevelServices(ProgressIndicator progressIndicator)
CoordinationService.Lock caseLock
static void addEventTypeSubscriber(Set< Events > eventTypes, PropertyChangeListener subscriber)
Void create(ProgressIndicator progressIndicator, Object additionalParams)
static StartupWindowProvider getInstance()
void setDeletedFlag(DeletedFlags flag)
void setLastAccessDate(Date lastAccessDate)
static CaseNodeData createCaseNodeData(final CaseMetadata metadata)
boolean isDeletedFlagSet(DeletedFlags flag)
static void writeCaseNodeData(CaseNodeData nodeData)
static CaseNodeData readCaseNodeData(String nodePath)
static String getCaseResourcesNodePath(Path caseDirectoryPath)
static String getCaseDirectoryNodePath(Path caseDirectoryPath)
KeywordSearchService getKeywordSearchService()
Lock tryGetExclusiveLock(CategoryNode category, String nodePath, int timeOut, TimeUnit timeUnit)
Lock tryGetSharedLock(CategoryNode category, String nodePath, int timeOut, TimeUnit timeUnit)
void deleteNode(CategoryNode category, String nodePath)
static synchronized CoordinationService getInstance()
static boolean runningWithGUI
static boolean getIsMultiUserModeEnabled()
static CaseDbConnectionInfo getDatabaseConnectionInfo()
static String getAppName()
static void openCoreWindows()
static void closeCoreWindows()
static boolean driveExists(String path)
static boolean deleteDir(File dirPath)
synchronized static Logger getLogger(String name)
synchronized static void setLogDirectory(String directoryPath)
static void error(String message)
static void error(String title, String message)
static String getLocalHostName()
static void shutDownTaskExecutor(ExecutorService executor)
static String convertToAlphaNumericFormat(String timeZoneId)
static String getVersion()
static synchronized DirectoryTreeTopComponent findInstance()
static boolean canAddDataSources()
static boolean canDeleteCurrentCase()
static synchronized IngestManager getInstance()
void cancelAllIngestJobs(IngestJob.CancellationReason reason)
static String getCustomTempDirectory()
static TempDirChoice getTempDirChoice()
static CaseType fromString(String typeName)
String getLocalizedDisplayName()
CaseType(String typeName)
boolean equalsName(String otherTypeName)
HOSTS_REMOVED_FROM_PERSON
ADDING_DATA_SOURCE_FAILED
BLACKBOARD_ARTIFACT_TAG_DELETED
BLACKBOARD_ARTIFACT_TAG_ADDED
R execute(T progressIndicator, V additionalParams)
void deleteDataSource(Long dataSourceId)
void start(String message, int totalWorkUnits)
void progress(String message)