Autopsy  4.17.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
CommandLineOptionProcessor.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019-2020 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.commandlineingest;
20 
21 import java.io.File;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28 import java.util.logging.Level;
30 import org.netbeans.api.sendopts.CommandException;
31 import org.netbeans.spi.sendopts.Env;
32 import org.netbeans.spi.sendopts.Option;
33 import org.netbeans.spi.sendopts.OptionProcessor;
34 import org.openide.util.lookup.ServiceProvider;
36 
40 @ServiceProvider(service = OptionProcessor.class)
41 public class CommandLineOptionProcessor extends OptionProcessor {
42 
43  private static final Logger logger = Logger.getLogger(CommandLineOptionProcessor.class.getName());
44  private final Option caseNameOption = Option.requiredArgument('n', "caseName");
45  private final Option caseTypeOption = Option.requiredArgument('t', "caseType");
46  private final Option caseBaseDirOption = Option.requiredArgument('o', "caseBaseDir");
47  private final Option createCaseCommandOption = Option.withoutArgument('c', "createCase");
48  private final Option dataSourcePathOption = Option.requiredArgument('s', "dataSourcePath");
49  private final Option dataSourceObjectIdOption = Option.requiredArgument('i', "dataSourceObjectId");
50  private final Option addDataSourceCommandOption = Option.withoutArgument('a', "addDataSource");
51  private final Option caseDirOption = Option.requiredArgument('d', "caseDir");
52  private final Option runIngestCommandOption = Option.optionalArgument('r', "runIngest");
53  private final Option listAllDataSourcesCommandOption = Option.withoutArgument('l', "listAllDataSources");
54  private final Option generateReportsOption = Option.optionalArgument('g', "generateReports");
55  private final Option defaultArgument = Option.defaultArguments();
56 
57  private boolean runFromCommandLine = false;
58 
59  private final List<CommandLineCommand> commands = new ArrayList<>();
60 
61  final static String CASETYPE_MULTI = "multi";
62  final static String CASETYPE_SINGLE = "single";
63 
64  private String defaultArgumentValue = null;
65 
66  @Override
67  protected Set<Option> getOptions() {
68  Set<Option> set = new HashSet<>();
69  set.add(createCaseCommandOption);
70  set.add(caseNameOption);
71  set.add(caseTypeOption);
72  set.add(caseBaseDirOption);
73  set.add(dataSourcePathOption);
74  set.add(addDataSourceCommandOption);
75  set.add(dataSourceObjectIdOption);
76  set.add(caseDirOption);
77  set.add(runIngestCommandOption);
78  set.add(listAllDataSourcesCommandOption);
79  set.add(generateReportsOption);
80  set.add(defaultArgument);
81  return set;
82  }
83 
84  @Override
85  protected void process(Env env, Map<Option, String[]> values) throws CommandException {
86  logger.log(Level.INFO, "Processing Autopsy command line options"); //NON-NLS
87  System.out.println("Processing Autopsy command line options");
88 
89  if (values.containsKey(defaultArgument)) {
90  defaultArgumentValue = values.get(defaultArgument)[0];
91  runFromCommandLine = true;
92  return;
93  }
94 
95  // input arguments must contain at least one command
96  if (!(values.containsKey(createCaseCommandOption) || values.containsKey(addDataSourceCommandOption)
97  || values.containsKey(runIngestCommandOption) || values.containsKey(listAllDataSourcesCommandOption)
98  || values.containsKey(generateReportsOption))) {
99  // not running from command line
100  handleError("Invalid command line, an input option must be supplied.");
101  }
102 
103  // parse input parameters
104  String[] argDirs;
105  String inputCaseName = "";
106  if (values.containsKey(caseNameOption)) {
107  argDirs = values.get(caseNameOption);
108  if (argDirs.length < 1) {
109  handleError("Missing argument 'caseName'");
110  }
111  inputCaseName = argDirs[0];
112 
113  if (inputCaseName == null || inputCaseName.isEmpty()) {
114  handleError("'caseName' argument is empty");
115  }
116  }
117 
118  String caseType = "";
119  if (values.containsKey(caseTypeOption)) {
120  argDirs = values.get(caseTypeOption);
121 
122  if (argDirs.length < 1) {
123  handleError("Missing argument 'caseType'");
124  }
125  caseType = argDirs[0];
126 
127  if (caseType == null || caseType.isEmpty()) {
128  handleError("'caseType' argument is empty");
129  } else if (!caseType.equalsIgnoreCase(CASETYPE_MULTI) && !caseType.equalsIgnoreCase(CASETYPE_SINGLE)) {
130  handleError("'caseType' argument is invalid");
131  } else if (caseType.equalsIgnoreCase(CASETYPE_MULTI) && !FeatureAccessUtils.canCreateMultiUserCases()) {
132  handleError("Unable to create multi user case. Confirm that multi user settings are configured correctly.");
133  }
134  }
135 
136  String caseBaseDir = "";
137  if (values.containsKey(caseBaseDirOption)) {
138  argDirs = values.get(caseBaseDirOption);
139  if (argDirs.length < 1) {
140  handleError("Missing argument 'caseBaseDir'");
141  }
142  caseBaseDir = argDirs[0];
143 
144  if (caseBaseDir == null || caseBaseDir.isEmpty()) {
145  handleError("Missing argument 'caseBaseDir' option");
146  }
147 
148  if (!(new File(caseBaseDir).exists()) || !(new File(caseBaseDir).isDirectory())) {
149  handleError("'caseBaseDir' directory doesn't exist or is not a directory: " + caseBaseDir);
150  }
151  }
152 
153  String dataSourcePath = "";
154  if (values.containsKey(dataSourcePathOption)) {
155 
156  argDirs = values.get(dataSourcePathOption);
157  if (argDirs.length < 1) {
158  handleError("Missing argument 'dataSourcePath'");
159  }
160  dataSourcePath = argDirs[0];
161 
162  // verify inputs
163  if (dataSourcePath == null || dataSourcePath.isEmpty()) {
164  handleError("Missing argument 'dataSourcePath'");
165  }
166 
167  if (!(new File(dataSourcePath).exists())) {
168  handleError("Input data source file " + dataSourcePath + " doesn't exist");
169  }
170  }
171 
172  String dataSourceId = "";
173  if (values.containsKey(dataSourceObjectIdOption)) {
174 
175  argDirs = values.get(dataSourceObjectIdOption);
176  if (argDirs.length < 1) {
177  handleError("Missing argument 'dataSourceObjectIdOption'");
178  }
179  dataSourceId = argDirs[0];
180 
181  // verify inputs
182  if (dataSourceId == null || dataSourceId.isEmpty()) {
183  handleError("Input data source id is empty");
184  }
185  }
186 
187  String caseDir = "";
188  if (values.containsKey(caseDirOption)) {
189 
190  argDirs = values.get(caseDirOption);
191  if (argDirs.length < 1) {
192  handleError("Argument missing from 'caseDir' option");
193  }
194  caseDir = argDirs[0];
195 
196  // verify inputs
197  if (caseDir == null || caseDir.isEmpty()) {
198  handleError("Argument missing from 'caseDir'");
199  }
200 
201  if (!(new File(caseDir).exists()) || !(new File(caseDir).isDirectory())) {
202  handleError("Case directory " + caseDir + " does not exist or is not a directory");
203  }
204  }
205 
206  // Create commands in order in which they should be executed:
207  // First create the "CREATE_CASE" command, if present
208  if (values.containsKey(createCaseCommandOption)) {
209 
210  // 'caseName' must always be specified for "CREATE_CASE" command
211  if (inputCaseName == null || inputCaseName.isEmpty()) {
212  handleError("'caseName' argument is empty");
213  }
214 
215  // 'caseBaseDir' must always be specified for "CREATE_CASE" command
216  if (caseBaseDir == null || caseBaseDir.isEmpty()) {
217  handleError("'caseBaseDir' argument is empty");
218  }
219 
220  CommandLineCommand newCommand = new CommandLineCommand(CommandLineCommand.CommandType.CREATE_CASE);
221  newCommand.addInputValue(CommandLineCommand.InputType.CASE_NAME.name(), inputCaseName);
222  newCommand.addInputValue(CommandLineCommand.InputType.CASES_BASE_DIR_PATH.name(), caseBaseDir);
223  newCommand.addInputValue(CommandLineCommand.InputType.CASE_TYPE.name(), caseType);
224  commands.add(newCommand);
225  runFromCommandLine = true;
226  }
227 
228  // Add ADD_DATA_SOURCE command, if present
229  if (values.containsKey(addDataSourceCommandOption)) {
230 
231  // 'caseDir' must only be specified if the case is not being created during the current run
232  if (!values.containsKey(createCaseCommandOption) && caseDir.isEmpty()) {
233  // new case is not being created during this run, so 'caseDir' should have been specified
234  handleError("'caseDir' argument is empty");
235  }
236 
237  // 'dataSourcePath' must always be specified for "ADD_DATA_SOURCE" command
238  if (dataSourcePath == null || dataSourcePath.isEmpty()) {
239  handleError("'dataSourcePath' argument is empty");
240  }
241 
242  CommandLineCommand newCommand = new CommandLineCommand(CommandLineCommand.CommandType.ADD_DATA_SOURCE);
243  newCommand.addInputValue(CommandLineCommand.InputType.CASE_FOLDER_PATH.name(), caseDir);
244  newCommand.addInputValue(CommandLineCommand.InputType.DATA_SOURCE_PATH.name(), dataSourcePath);
245  commands.add(newCommand);
246  runFromCommandLine = true;
247  }
248 
249  String ingestProfile = "";
250  // Add RUN_INGEST command, if present
251  if (values.containsKey(runIngestCommandOption)) {
252 
253  argDirs = values.get(runIngestCommandOption);
254  if(argDirs != null && argDirs.length > 0) {
255  ingestProfile = argDirs[0];
256  }
257 
258  // 'caseDir' must only be specified if the case is not being created during the current run
259  if (!values.containsKey(createCaseCommandOption) && caseDir.isEmpty()) {
260  // new case is not being created during this run, so 'caseDir' should have been specified
261  handleError("'caseDir' argument is empty");
262  }
263 
264  // if new data source is being added during this run, then 'dataSourceId' is not specified
265  if (!values.containsKey(addDataSourceCommandOption) && dataSourceId.isEmpty()) {
266  // data source is not being added during this run, so 'dataSourceId' should have been specified
267  handleError("'dataSourceId' argument is empty");
268  }
269 
270  CommandLineCommand newCommand = new CommandLineCommand(CommandLineCommand.CommandType.RUN_INGEST);
271  newCommand.addInputValue(CommandLineCommand.InputType.CASE_FOLDER_PATH.name(), caseDir);
272  newCommand.addInputValue(CommandLineCommand.InputType.DATA_SOURCE_ID.name(), dataSourceId);
273  newCommand.addInputValue(CommandLineCommand.InputType.INGEST_PROFILE_NAME.name(), ingestProfile);
274  commands.add(newCommand);
275  runFromCommandLine = true;
276  }
277 
278  // Add "LIST_ALL_DATA_SOURCES" command, if present
279  if (values.containsKey(listAllDataSourcesCommandOption)) {
280 
281  // 'caseDir' must only be specified if the case is not being created during the current run
282  if (!values.containsKey(createCaseCommandOption) && (caseDir == null || caseDir.isEmpty())) {
283  // new case is not being created during this run, so 'caseDir' should have been specified
284  handleError("'caseDir' argument is empty");
285  }
286 
287  CommandLineCommand newCommand = new CommandLineCommand(CommandLineCommand.CommandType.LIST_ALL_DATA_SOURCES);
288  newCommand.addInputValue(CommandLineCommand.InputType.CASE_FOLDER_PATH.name(), caseDir);
289  commands.add(newCommand);
290  runFromCommandLine = true;
291  }
292 
293  // Add "GENERATE_REPORTS" command, if present
294  String reportProfile = null;
295  if (values.containsKey(generateReportsOption)) {
296 
297  // 'caseDir' must only be specified if the case is not being created during the current run
298  if (!values.containsKey(createCaseCommandOption) && caseDir.isEmpty()) {
299  // new case is not being created during this run, so 'caseDir' should have been specified
300  handleError("'caseDir' argument is empty");
301  }
302 
303  argDirs = values.get(generateReportsOption);
304  if (argDirs.length > 0) {
305  reportProfile = argDirs[0];
306  }
307 
308  // If the user doesn't supply an options for generateReports the
309  // argsDirs length will be 0, so if reportProfile is empty
310  // something is not right.
311  if (reportProfile != null && reportProfile.isEmpty()) {
312  handleError("'generateReports' argument is empty");
313  }
314 
315  CommandLineCommand newCommand = new CommandLineCommand(CommandLineCommand.CommandType.GENERATE_REPORTS);
316  newCommand.addInputValue(CommandLineCommand.InputType.CASE_FOLDER_PATH.name(), caseDir);
317  if (reportProfile != null) {
318  newCommand.addInputValue(CommandLineCommand.InputType.REPORT_PROFILE_NAME.name(), reportProfile);
319  }
320  commands.add(newCommand);
321  runFromCommandLine = true;
322  }
323  }
324 
330  public boolean isRunFromCommandLine() {
331  return runFromCommandLine;
332  }
333 
339  public String getDefaultArgument() {
340  return defaultArgumentValue;
341  }
342 
348  List<CommandLineCommand> getCommands() {
349  return Collections.unmodifiableList(commands);
350  }
351 
359  private void handleError(String errorMessage) throws CommandException {
360  logger.log(Level.SEVERE, errorMessage);
361  throw new CommandException(1, errorMessage);
362  }
363 }
synchronized static Logger getLogger(String name)
Definition: Logger.java:124

Copyright © 2012-2021 Basis Technology. Generated on: Tue Jan 19 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.