19 package org.sleuthkit.autopsy.commandlineingest;
21 import java.beans.PropertyChangeListener;
22 import java.beans.PropertyChangeSupport;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashSet;
27 import java.util.List;
30 import java.util.logging.Level;
31 import java.util.stream.Collectors;
32 import java.util.stream.Stream;
34 import org.netbeans.api.sendopts.CommandException;
35 import org.netbeans.spi.sendopts.Env;
36 import org.netbeans.spi.sendopts.Option;
37 import org.netbeans.spi.sendopts.OptionProcessor;
38 import org.openide.util.lookup.ServiceProvider;
44 @ServiceProvider(service = OptionProcessor.class)
48 private final Option caseNameOption = Option.requiredArgument(
'n',
"caseName");
49 private final Option caseTypeOption = Option.requiredArgument(
't',
"caseType");
50 private final Option caseBaseDirOption = Option.requiredArgument(
'o',
"caseBaseDir");
51 private final Option createCaseCommandOption = Option.withoutArgument(
'c',
"createCase");
52 private final Option dataSourcePathOption = Option.requiredArgument(
's',
"dataSourcePath");
53 private final Option dataSourceObjectIdOption = Option.requiredArgument(
'i',
"dataSourceObjectId");
54 private final Option addDataSourceCommandOption = Option.withoutArgument(
'a',
"addDataSource");
55 private final Option runIngestCommandOption = Option.optionalArgument(
'r',
"runIngest");
56 private final Option listAllDataSourcesCommandOption = Option.withoutArgument(
'l',
"listAllDataSources");
57 private final Option generateReportsOption = Option.optionalArgument(
'g',
"generateReports");
58 private final Option listAllIngestProfileOption = Option.withoutArgument(
'p',
"listAllIngestProfiles");
59 private final Option defaultArgument = Option.defaultArguments();
61 private boolean runFromCommandLine =
false;
63 private final List<CommandLineCommand> commands =
new ArrayList<>();
65 final static String CASETYPE_MULTI =
"multi";
66 final static String CASETYPE_SINGLE =
"single";
68 private String defaultArgumentValue = null;
70 private PropertyChangeSupport changes =
new PropertyChangeSupport(
this);
71 public static String PROCESSING_STARTED =
"command line process started";
72 public static String PROCESSING_COMPLETED =
"command line process completed";
84 Set<Option> set =
new HashSet<>();
85 set.add(createCaseCommandOption);
86 set.add(caseNameOption);
87 set.add(caseTypeOption);
88 set.add(caseBaseDirOption);
89 set.add(dataSourcePathOption);
90 set.add(addDataSourceCommandOption);
91 set.add(dataSourceObjectIdOption);
92 set.add(runIngestCommandOption);
93 set.add(listAllDataSourcesCommandOption);
94 set.add(generateReportsOption);
95 set.add(listAllIngestProfileOption);
96 set.add(defaultArgument);
101 protected void process(Env env, Map<Option, String[]> values) throws CommandException {
102 logger.log(Level.INFO,
"Processing Autopsy command line options");
103 System.out.println(
"Processing Autopsy command line options");
105 changes.firePropertyChange(PROCESSING_STARTED,
false,
true);
107 if (values.containsKey(defaultArgument)) {
108 defaultArgumentValue = values.get(defaultArgument)[0];
109 runFromCommandLine(
true);
114 if (!(values.containsKey(createCaseCommandOption) || values.containsKey(addDataSourceCommandOption)
115 || values.containsKey(runIngestCommandOption) || values.containsKey(listAllDataSourcesCommandOption)
116 || values.containsKey(generateReportsOption) || values.containsKey(listAllIngestProfileOption))) {
118 handleError(
"Invalid command line, an input option must be supplied.");
123 String inputCaseName =
"";
125 if(values.containsKey(listAllIngestProfileOption)) {
126 CommandLineCommand newCommand =
new CommandLineCommand(CommandLineCommand.CommandType.LIST_ALL_INGEST_PROFILES);
127 commands.add(newCommand);
128 runFromCommandLine(
true);
130 if (values.containsKey(caseNameOption)) {
131 argDirs = values.get(caseNameOption);
132 if (argDirs.length < 1) {
133 handleError(
"Missing argument 'caseName'");
135 inputCaseName = argDirs[0];
137 if (inputCaseName == null || inputCaseName.isEmpty()) {
138 handleError(
"'caseName' argument is empty");
143 if (inputCaseName == null || inputCaseName.isEmpty()) {
144 handleError(
"'caseName' argument is empty");
147 String caseType =
"";
148 if (values.containsKey(caseTypeOption)) {
149 argDirs = values.get(caseTypeOption);
151 if (argDirs.length < 1) {
152 handleError(
"Missing argument 'caseType'");
154 caseType = argDirs[0];
156 if (caseType == null || caseType.isEmpty()) {
157 handleError(
"'caseType' argument is empty");
158 }
else if (!caseType.equalsIgnoreCase(CASETYPE_MULTI) && !caseType.equalsIgnoreCase(CASETYPE_SINGLE)) {
159 handleError(
"'caseType' argument is invalid");
161 handleError(
"Unable to create multi user case. Confirm that multi user settings are configured correctly.");
165 String caseBaseDir =
"";
166 if (values.containsKey(caseBaseDirOption)) {
167 argDirs = values.get(caseBaseDirOption);
168 if (argDirs.length < 1) {
169 handleError(
"Missing argument 'caseBaseDir'");
171 caseBaseDir = argDirs[0];
173 if (caseBaseDir == null || caseBaseDir.isEmpty()) {
174 handleError(
"Missing argument 'caseBaseDir' option");
177 if (!(
new File(caseBaseDir).exists()) || !(
new File(caseBaseDir).isDirectory())) {
178 handleError(
"'caseBaseDir' directory doesn't exist or is not a directory: " + caseBaseDir);
183 if (caseBaseDir == null || caseBaseDir.isEmpty()) {
184 handleError(
"Missing argument 'caseBaseDir' option");
187 String dataSourcePath =
"";
188 if (values.containsKey(dataSourcePathOption)) {
190 argDirs = values.get(dataSourcePathOption);
191 if (argDirs.length < 1) {
192 handleError(
"Missing argument 'dataSourcePath'");
194 dataSourcePath = argDirs[0];
197 if (dataSourcePath == null || dataSourcePath.isEmpty()) {
198 handleError(
"Missing argument 'dataSourcePath'");
201 if (!(
new File(dataSourcePath).exists())) {
202 handleError(
"Input data source file " + dataSourcePath +
" doesn't exist");
206 String dataSourceId =
"";
207 if (values.containsKey(dataSourceObjectIdOption)) {
209 argDirs = values.get(dataSourceObjectIdOption);
210 if (argDirs.length < 1) {
211 handleError(
"Missing argument 'dataSourceObjectIdOption'");
213 dataSourceId = argDirs[0];
216 if (dataSourceId == null || dataSourceId.isEmpty()) {
217 handleError(
"Input data source id is empty");
223 if (values.containsKey(createCaseCommandOption)) {
226 if (inputCaseName == null || inputCaseName.isEmpty()) {
227 handleError(
"'caseName' argument is empty");
230 CommandLineCommand newCommand =
new CommandLineCommand(CommandLineCommand.CommandType.CREATE_CASE);
231 newCommand.addInputValue(CommandLineCommand.InputType.CASE_NAME.name(), inputCaseName);
232 newCommand.addInputValue(CommandLineCommand.InputType.CASES_BASE_DIR_PATH.name(), caseBaseDir);
233 newCommand.addInputValue(CommandLineCommand.InputType.CASE_TYPE.name(), caseType);
234 commands.add(newCommand);
235 runFromCommandLine(
true);
239 if (values.containsKey(addDataSourceCommandOption)) {
242 if (dataSourcePath == null || dataSourcePath.isEmpty()) {
243 handleError(
"'dataSourcePath' argument is empty");
246 CommandLineCommand newCommand =
new CommandLineCommand(CommandLineCommand.CommandType.ADD_DATA_SOURCE);
247 newCommand.addInputValue(CommandLineCommand.InputType.CASE_NAME.name(), inputCaseName);
248 newCommand.addInputValue(CommandLineCommand.InputType.CASES_BASE_DIR_PATH.name(), caseBaseDir);
249 newCommand.addInputValue(CommandLineCommand.InputType.DATA_SOURCE_PATH.name(), dataSourcePath);
250 commands.add(newCommand);
251 runFromCommandLine(
true);
254 String ingestProfile =
"";
256 if (values.containsKey(runIngestCommandOption)) {
258 argDirs = values.get(runIngestCommandOption);
259 if(argDirs != null && argDirs.length > 0) {
260 ingestProfile = argDirs[0];
264 if (!values.containsKey(addDataSourceCommandOption) && dataSourceId.isEmpty()) {
266 handleError(
"'dataSourceId' argument is empty");
269 CommandLineCommand newCommand =
new CommandLineCommand(CommandLineCommand.CommandType.RUN_INGEST);
270 newCommand.addInputValue(CommandLineCommand.InputType.CASE_NAME.name(), inputCaseName);
271 newCommand.addInputValue(CommandLineCommand.InputType.CASES_BASE_DIR_PATH.name(), caseBaseDir);
272 newCommand.addInputValue(CommandLineCommand.InputType.DATA_SOURCE_ID.name(), dataSourceId);
273 newCommand.addInputValue(CommandLineCommand.InputType.INGEST_PROFILE_NAME.name(), ingestProfile);
274 newCommand.addInputValue(CommandLineCommand.InputType.DATA_SOURCE_PATH.name(), dataSourcePath);
275 commands.add(newCommand);
276 runFromCommandLine(
true);
280 if (values.containsKey(listAllDataSourcesCommandOption)) {
282 CommandLineCommand newCommand =
new CommandLineCommand(CommandLineCommand.CommandType.LIST_ALL_DATA_SOURCES);
283 newCommand.addInputValue(CommandLineCommand.InputType.CASE_NAME.name(), inputCaseName);
284 newCommand.addInputValue(CommandLineCommand.InputType.CASES_BASE_DIR_PATH.name(), caseBaseDir);
285 commands.add(newCommand);
286 runFromCommandLine(
true);
290 if (values.containsKey(generateReportsOption)) {
291 List<String> reportProfiles;
292 argDirs = values.get(generateReportsOption);
293 if (argDirs.length > 0) {
295 reportProfiles = Stream.of(argDirs[0].split(
","))
297 .collect(Collectors.toList());
299 if (reportProfiles == null || reportProfiles.isEmpty()) {
300 handleError(
"'generateReports' argument is empty");
303 for (String reportProfile : reportProfiles) {
304 if (reportProfile.isEmpty()) {
305 handleError(
"Empty report profile name");
307 CommandLineCommand newCommand =
new CommandLineCommand(CommandLineCommand.CommandType.GENERATE_REPORTS);
308 newCommand.addInputValue(CommandLineCommand.InputType.CASE_NAME.name(), inputCaseName);
309 newCommand.addInputValue(CommandLineCommand.InputType.CASES_BASE_DIR_PATH.name(), caseBaseDir);
310 newCommand.addInputValue(CommandLineCommand.InputType.REPORT_PROFILE_NAME.name(), reportProfile);
311 commands.add(newCommand);
315 CommandLineCommand newCommand =
new CommandLineCommand(CommandLineCommand.CommandType.GENERATE_REPORTS);
316 newCommand.addInputValue(CommandLineCommand.InputType.CASE_NAME.name(), inputCaseName);
317 newCommand.addInputValue(CommandLineCommand.InputType.CASES_BASE_DIR_PATH.name(), caseBaseDir);
318 commands.add(newCommand);
321 runFromCommandLine(
true);
326 System.out.println(
"Completed processing Autopsy command line options");
327 changes.firePropertyChange(PROCESSING_COMPLETED,
false,
true);
336 return runFromCommandLine;
340 this.runFromCommandLine = runFromCommandLine;
349 return defaultArgumentValue;
357 List<CommandLineCommand> getCommands() {
358 return Collections.unmodifiableList(commands);
368 private void handleError(String errorMessage)
throws CommandException {
369 logger.log(Level.SEVERE, errorMessage);
374 PropertyChangeListener l) {
375 changes.addPropertyChangeListener(l);
378 PropertyChangeListener l) {
379 changes.removePropertyChangeListener(l);
synchronized void runFromCommandLine(boolean runFromCommandLine)
synchronized boolean isRunFromCommandLine()
String getDefaultArgument()
void removePropertyChangeListener(PropertyChangeListener l)
void addPropertyChangeListener(PropertyChangeListener l)
synchronized void setState(ProcessState state)
void handleError(String errorMessage)
static boolean canCreateMultiUserCases()
synchronized static Logger getLogger(String name)
synchronized ProcessState getState()
Set< Option > getOptions()
void process(Env env, Map< Option, String[]> values)