Autopsy  4.14.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
CreateLiveTriageDriveAction.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2018 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.livetriage;
20 
21 import java.io.IOException;
22 import java.nio.file.Path;
23 import java.nio.file.Paths;
24 import java.nio.file.InvalidPathException;
25 import java.util.logging.Level;
26 import java.beans.PropertyChangeListener;
27 import java.beans.PropertyChangeEvent;
28 import javax.swing.JOptionPane;
29 import java.awt.Frame;
30 import javax.swing.SwingWorker;
31 import org.apache.commons.io.FileUtils;
32 import org.openide.awt.ActionID;
33 import org.openide.awt.ActionReference;
34 import org.openide.awt.ActionRegistration;
35 import org.openide.util.HelpCtx;
36 import org.openide.util.NbBundle;
37 import org.openide.util.actions.CallableSystemAction;
38 import org.openide.windows.WindowManager;
44 
45 @ActionID(category = "Tools", id = "org.sleuthkit.autopsy.livetriage.CreateLiveTriageDriveAction")
46 @ActionReference(path = "Menu/Tools", position = 1850, separatorBefore = 1849)
47 @ActionRegistration(displayName = "#CTL_CreateLiveTriageDriveAction", lazy = false)
48 @NbBundle.Messages({"CTL_CreateLiveTriageDriveAction=Make Live Triage Drive"})
49 public final class CreateLiveTriageDriveAction extends CallableSystemAction implements PropertyChangeListener {
50 
51  private static final String DISPLAY_NAME = Bundle.CTL_CreateLiveTriageDriveAction();
52  private ModalDialogProgressIndicator progressIndicator = null;
53  private String drivePath = "";
55 
56  @Override
57  public boolean isEnabled() {
58  return true;
59  }
60 
61  @NbBundle.Messages({"CreateLiveTriageDriveAction.error.title=Error creating live triage disk",
62  "CreateLiveTriageDriveAction.exenotfound.message=Executable could not be found",
63  "CreateLiveTriageDriveAction.batchFileError.message=Error creating batch file",
64  "CreateLiveTriageDriveAction.appPathError.message=Could not location application directory",
65  "CreateLiveTriageDriveAction.copyError.message=Could not copy application. Only works on installed version.",
66  "CreateLiveTriageDriveAction.success.title=Success",
67  "CreateLiveTriageDriveAction.success.message=Live triage drive created. Use RunFromUSB.bat to run the application"
68  })
69  @Override
70  @SuppressWarnings("fallthrough")
71  public void performAction() {
72 
73  Frame mainWindow = WindowManager.getDefault().getMainWindow();
74 
75  // If this is an installed version, there should be an <appName>64.exe file in the bin folder
76  String appName = UserPreferences.getAppName();
77  String exeName = appName + "64.exe";
78  String installPath = PlatformUtil.getInstallPath();
79 
80  Path exePath = Paths.get(installPath, "bin", exeName);
81 
82  if (!exePath.toFile().exists()) {
83  JOptionPane.showMessageDialog(mainWindow,
84  Bundle.CreateLiveTriageDriveAction_exenotfound_message(),
85  Bundle.CreateLiveTriageDriveAction_error_title(),
86  JOptionPane.ERROR_MESSAGE);
87  return;
88  }
89 
90  Path applicationBasePath;
91  try {
92  applicationBasePath = exePath.getParent().getParent();
93  } catch (InvalidPathException ex) {
94  JOptionPane.showMessageDialog(mainWindow,
95  Bundle.CreateLiveTriageDriveAction_appPathError_message(),
96  Bundle.CreateLiveTriageDriveAction_error_title(),
97  JOptionPane.ERROR_MESSAGE);
98  return;
99  }
100 
101  SelectDriveDialog driveDialog = new SelectDriveDialog(mainWindow, true);
102  driveDialog.display();
103 
104  if (!driveDialog.getSelectedDrive().isEmpty()) {
105  drivePath = driveDialog.getSelectedDrive();
106  if (drivePath.startsWith("\\\\.\\")) {
107  drivePath = drivePath.substring(4);
108  }
109 
110  worker = new CopyFilesWorker(applicationBasePath, drivePath, appName);
111  worker.addPropertyChangeListener(this);
112  worker.execute();
113  }
114  }
115 
116  @NbBundle.Messages({"# {0} - drivePath",
117  "CreateLiveTriageDriveAction.progressBar.text=Copying live triage files to {0}",
118  "CreateLiveTriageDriveAction.progressBar.title=Please wait"})
119  @Override
120  public void propertyChange(PropertyChangeEvent evt) {
121 
122  if ("state".equals(evt.getPropertyName())
123  && (SwingWorker.StateValue.STARTED.equals(evt.getNewValue()))) {
124 
125  // Setup progress bar.
126  String displayStr = NbBundle.getMessage(this.getClass(), "CreateLiveTriageDriveAction.progressBar.text",
127  drivePath);
128 
129  progressIndicator = new ModalDialogProgressIndicator(WindowManager.getDefault().getMainWindow(),
130  NbBundle.getMessage(this.getClass(), "CreateLiveTriageDriveAction.progressBar.title"));
131  progressIndicator.start(displayStr);
132 
133  } else if ("state".equals(evt.getPropertyName())
134  && (SwingWorker.StateValue.DONE.equals(evt.getNewValue()))) {
135  if (progressIndicator != null) {
136  progressIndicator.finish();
137  }
138 
139  if (worker.hadError()) {
140  MessageNotifyUtil.Message.error(NbBundle.getMessage(CopyFilesWorker.class, "CopyFilesWorker.error.text"));
141  } else {
142  MessageNotifyUtil.Message.info(NbBundle.getMessage(CopyFilesWorker.class, "CopyFilesWorker.done.text"));
143  }
144  }
145  }
146 
147  private class CopyFilesWorker extends SwingWorker<Void, Void> {
148 
149  private final Path sourceFolder;
150  private final String drivePath;
151  private final String appName;
152  private boolean error = false;
153 
154  CopyFilesWorker(Path sourceFolder, String drivePath, String appName) {
155  this.sourceFolder = sourceFolder;
156  this.drivePath = drivePath;
157  this.appName = appName;
158  }
159 
160  boolean hadError() {
161  return error;
162  }
163 
164  @Override
165  protected Void doInBackground() throws Exception {
166 
167  copyBatchFile(drivePath, appName);
168  copyApplication(sourceFolder, drivePath, appName);
169 
170  return null;
171  }
172 
173  @NbBundle.Messages({"CopyFilesWorker.error.text=Error copying live triage files",
174  "CopyFilesWorker.done.text=Finished creating live triage disk"})
175  @Override
176  protected void done() {
177  try {
178  super.get();
179  } catch (Exception ex) {
180  error = true;
181  Logger.getLogger(CreateLiveTriageDriveAction.class.getName()).log(Level.SEVERE, "Fatal error during live triage drive creation", ex); //NON-NLS
182  }
183  }
184  }
185 
186  private void copyApplication(Path sourceFolder, String destBaseFolder, String appName) throws IOException {
187 
188  // Create an appName folder in the destination
189  Path destAppFolder = Paths.get(destBaseFolder, appName);
190  if (!destAppFolder.toFile().exists()) {
191  if (!destAppFolder.toFile().mkdirs()) {
192  throw new IOException("Failed to create directory " + destAppFolder.toString());
193  }
194  }
195 
196  // Now copy the files
197  FileUtils.copyDirectory(sourceFolder.toFile(), destAppFolder.toFile());
198  }
199 
200  private void copyBatchFile(String destPath, String appName) throws IOException, InvalidPathException {
201  Path batchFilePath = Paths.get(destPath, "RunFromUSB.bat");
202  FileUtils.writeStringToFile(batchFilePath.toFile(), getBatchFileContents(appName), "UTF-8");
203 
204  }
205 
206  private String getBatchFileContents(String appName) {
207 
208  String batchFile
209  = "@echo off\n"
210  + "\n"
211  + "REM This restores the working directory when using 'Run as administrator'"
212  + "@setlocal enableextensions\n"
213  + "@cd /d \"%~dp0\""
214  + "\n"
215  + "SET appName=\"" + appName + "\"\n"
216  + "\n"
217  + "REM Create the configData directory. Exit if it does not exist after attempting to create it\n"
218  + "if not exist configData mkdir configData\n"
219  + "if not exist configData (\n"
220  + " echo Error creating directory configData\n"
221  + " goto end\n"
222  + ")\n"
223  + "\n"
224  + "REM Create the userdir sub directory. Exit if it does not exist after attempting to create it\n"
225  + "if not exist configData\\userdir mkdir configData\\userdir\n"
226  + "if not exist configData\\userdir (\n"
227  + " echo Error creating directory configData\\userdir\n"
228  + " goto end\n"
229  + ")\n"
230  + "\n"
231  + "REM Create the cachedir sub directory. Exit if it does not exist after attempting to create it\n"
232  + "REM If it exists to start with, delete it to clear out old data\n"
233  + "if exist configData\\cachedir rd /s /q configData\\cachedir\n"
234  + "mkdir configData\\cachedir\n"
235  + "if not exist configData\\cachedir (\n"
236  + " echo Error creating directory configData\\cachedir\n"
237  + " goto end\n"
238  + ")\n"
239  + "\n"
240  + "REM Create the temp sub directory. Exit if it does not exist after attempting to create it\n"
241  + "REM If it exists to start with, delete it to clear out old data\n"
242  + "if exist configData\\temp rd /s /q configData\\temp\n"
243  + "mkdir configData\\temp\n"
244  + "if not exist configData\\temp (\n"
245  + " echo Error creating directory configData\\temp\n"
246  + " goto end\n"
247  + ")\n"
248  + "\n"
249  + "REM Create the cases directory. It's ok if this fails.\n"
250  + "if not exist cases mkdir cases\n"
251  + "\n"
252  + "if exist %appName% (\n"
253  + " if not exist %appName%\\bin\\%appName%64.exe (\n"
254  + " echo %appName%\\bin\\%appName%64.exe does not exist\n"
255  + " goto end\n"
256  + " )\n"
257  + " %appName%\\bin\\%appName%64.exe --userdir ..\\configData\\userdir --cachedir ..\\configData\\cachedir -J-Djava.io.tmpdir=..\\configData\\temp --liveAutopsy\n"
258  + ") else (\n"
259  + " echo Could not find %appName% directory\n"
260  + " goto end\n"
261  + ")\n"
262  + "\n"
263  + ":end\n"
264  + "\n"
265  + "REM Keep the cmd window open in case there was an error\n"
266  + "@pause\n";
267  return batchFile;
268  }
269 
270  @Override
271  public String getName() {
272  return DISPLAY_NAME;
273  }
274 
275  @Override
276  public HelpCtx getHelpCtx() {
277  return HelpCtx.DEFAULT_HELP;
278  }
279 
280  @Override
281  public boolean asynchronous() {
282  return false; // run on edt
283  }
284 }
void copyApplication(Path sourceFolder, String destBaseFolder, String appName)
synchronized void start(String message, int totalWorkUnits)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

Copyright © 2012-2020 Basis Technology. Generated on: Wed Apr 8 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.