View Javadoc
1   /*
2    * This file is part of dependency-check-cli.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Copyright (c) 2012 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck;
19  
20  import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
21  
22  import java.io.File;
23  import java.io.FileNotFoundException;
24  
25  import org.apache.commons.cli.CommandLine;
26  import org.apache.commons.cli.CommandLineParser;
27  import org.apache.commons.cli.DefaultParser;
28  import org.apache.commons.cli.HelpFormatter;
29  import org.apache.commons.cli.Option;
30  import org.apache.commons.cli.OptionGroup;
31  import org.apache.commons.cli.Options;
32  import org.apache.commons.cli.ParseException;
33  import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
34  import org.owasp.dependencycheck.utils.InvalidSettingException;
35  import org.owasp.dependencycheck.utils.Settings;
36  import org.slf4j.Logger;
37  import org.slf4j.LoggerFactory;
38  
39  /**
40   * A utility to parse command line arguments for the DependencyCheck.
41   *
42   * @author Jeremy Long
43   */
44  //suppress hard-coded password rule
45  @SuppressWarnings("squid:S2068")
46  public final class CliParser {
47  
48      /**
49       * The logger.
50       */
51      private static final Logger LOGGER = LoggerFactory.getLogger(CliParser.class);
52      /**
53       * The command line.
54       */
55      private CommandLine line;
56      /**
57       * Indicates whether the arguments are valid.
58       */
59      private boolean isValid = true;
60      /**
61       * The configured settings.
62       */
63      private final Settings settings;
64      /**
65       * The supported reported formats.
66       */
67      private static final String SUPPORTED_FORMATS = "HTML, XML, CSV, JSON, JUNIT, SARIF, JENKINS, GITLAB or ALL";
68  
69      /**
70       * Constructs a new CLI Parser object with the configured settings.
71       *
72       * @param settings the configured settings
73       */
74      public CliParser(Settings settings) {
75          this.settings = settings;
76      }
77  
78      /**
79       * Parses the arguments passed in and captures the results for later use.
80       *
81       * @param args the command line arguments
82       * @throws FileNotFoundException is thrown when a 'file' argument does not
83       * point to a file that exists.
84       * @throws ParseException is thrown when a Parse Exception occurs.
85       */
86      public void parse(String[] args) throws FileNotFoundException, ParseException {
87          line = parseArgs(args);
88  
89          if (line != null) {
90              validateArgs();
91          }
92      }
93  
94      /**
95       * Parses the command line arguments.
96       *
97       * @param args the command line arguments
98       * @return the results of parsing the command line arguments
99       * @throws ParseException if the arguments are invalid
100      */
101     private CommandLine parseArgs(String[] args) throws ParseException {
102         final CommandLineParser parser = new DefaultParser();
103         final Options options = createCommandLineOptions();
104         return parser.parse(options, args);
105     }
106 
107     /**
108      * Validates that the command line arguments are valid.
109      *
110      * @throws FileNotFoundException if there is a file specified by either the
111      * SCAN or CPE command line arguments that does not exist.
112      * @throws ParseException is thrown if there is an exception parsing the
113      * command line.
114      */
115     private void validateArgs() throws FileNotFoundException, ParseException {
116         if (isUpdateOnly() || isRunScan()) {
117 
118             String value = line.getOptionValue(ARGUMENT.NVD_API_VALID_FOR_HOURS);
119             if (value != null) {
120                 try {
121                     final int i = Integer.parseInt(value);
122                     if (i < 0) {
123                         throw new ParseException("Invalid Setting: nvdValidForHours must be a number greater than or equal to 0.");
124                     }
125                 } catch (NumberFormatException ex) {
126                     throw new ParseException("Invalid Setting: nvdValidForHours must be a number greater than or equal to 0.");
127                 }
128             }
129             value = line.getOptionValue(ARGUMENT.NVD_API_MAX_RETRY_COUNT);
130             if (value != null) {
131                 try {
132                     final int i = Integer.parseInt(value);
133                     if (i <= 0) {
134                         throw new ParseException("Invalid Setting: nvdMaxRetryCount must be a number greater than 0.");
135                     }
136                 } catch (NumberFormatException ex) {
137                     throw new ParseException("Invalid Setting: nvdMaxRetryCount must be a number greater than 0.");
138                 }
139             }
140             value = line.getOptionValue(ARGUMENT.NVD_API_DELAY);
141             if (value != null) {
142                 try {
143                     final int i = Integer.parseInt(value);
144                     if (i < 0) {
145                         throw new ParseException("Invalid Setting: nvdApiDelay must be a number greater than or equal to 0.");
146                     }
147                 } catch (NumberFormatException ex) {
148                     throw new ParseException("Invalid Setting: nvdApiDelay must be a number greater than or equal to 0.");
149                 }
150             }
151         }
152         if (isRunScan()) {
153             validatePathExists(getScanFiles(), ARGUMENT.SCAN);
154             validatePathExists(getReportDirectory(), ARGUMENT.OUT);
155             final String pathToCore = getStringArgument(ARGUMENT.PATH_TO_CORE);
156             if (pathToCore != null) {
157                 validatePathExists(pathToCore, ARGUMENT.PATH_TO_CORE);
158             }
159             if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
160                 for (String validating : getReportFormat()) {
161                     if (!isValidFormat(validating)
162                             && !isValidFilePath(validating, "format")) {
163                         final String msg = String.format("An invalid 'format' of '%s' was specified. "
164                                 + "Supported output formats are %s, and custom template files.",
165                                 validating, SUPPORTED_FORMATS);
166                         throw new ParseException(msg);
167                     }
168                 }
169             }
170             if (line.hasOption(ARGUMENT.SYM_LINK_DEPTH)) {
171                 try {
172                     final int i = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH));
173                     if (i < 0) {
174                         throw new ParseException("Symbolic Link Depth (symLink) must be greater than zero.");
175                     }
176                 } catch (NumberFormatException ex) {
177                     throw new ParseException("Symbolic Link Depth (symLink) is not a number.");
178                 }
179             }
180         }
181     }
182 
183     /**
184      * Validates the format to be one of the known Formats.
185      *
186      * @param format the format to validate
187      * @return true, if format is known in Format; false otherwise
188      * @see Format
189      */
190     private boolean isValidFormat(String format) {
191         try {
192             Format.valueOf(format);
193             return true;
194         } catch (IllegalArgumentException ex) {
195             return false;
196         }
197     }
198 
199     /**
200      * Validates the path to point at an existing file.
201      *
202      * @param path the path to validate if it exists
203      * @param argumentName the argument being validated (e.g. scan, out, etc.)
204      * @return true, if path exists; false otherwise
205      */
206     private boolean isValidFilePath(String path, String argumentName) {
207         try {
208             validatePathExists(path, argumentName);
209             return true;
210         } catch (FileNotFoundException ex) {
211             return false;
212         }
213     }
214 
215     /**
216      * Validates whether or not the path(s) points at a file that exists; if the
217      * path(s) does not point to an existing file a FileNotFoundException is
218      * thrown.
219      *
220      * @param paths the paths to validate if they exists
221      * @param optType the option being validated (e.g. scan, out, etc.)
222      * @throws FileNotFoundException is thrown if one of the paths being
223      * validated does not exist.
224      */
225     private void validatePathExists(String[] paths, String optType) throws FileNotFoundException {
226         for (String path : paths) {
227             validatePathExists(path, optType);
228         }
229     }
230 
231     /**
232      * Validates whether or not the path points at a file that exists; if the
233      * path does not point to an existing file a FileNotFoundException is
234      * thrown.
235      *
236      * @param path the paths to validate if they exists
237      * @param argumentName the argument being validated (e.g. scan, out, etc.)
238      * @throws FileNotFoundException is thrown if the path being validated does
239      * not exist.
240      */
241     private void validatePathExists(String path, String argumentName) throws FileNotFoundException {
242         if (path == null) {
243             isValid = false;
244             final String msg = String.format("Invalid '%s' argument: null", argumentName);
245             throw new FileNotFoundException(msg);
246         } else if (!path.contains("*") && !path.contains("?")) {
247             File f = new File(path);
248             final String[] formats = this.getReportFormat();
249             if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && formats.length == 1 && !"ALL".equalsIgnoreCase(formats[0])) {
250                 final String checkPath = path.toLowerCase();
251                 if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")
252                         || checkPath.endsWith(".csv") || checkPath.endsWith(".json")) {
253                     if (f.getParentFile() == null) {
254                         f = new File(".", path);
255                     }
256                     if (!f.getParentFile().isDirectory()) {
257                         isValid = false;
258                         final String msg = String.format("Invalid '%s' argument: '%s' - directory path does not exist", argumentName, path);
259                         throw new FileNotFoundException(msg);
260                     }
261                 }
262             } else if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && !f.isDirectory()) {
263                 if (f.getParentFile() != null && f.getParentFile().isDirectory() && !f.mkdir()) {
264                     isValid = false;
265                     final String msg = String.format("Invalid '%s' argument: '%s' - unable to create the output directory", argumentName, path);
266                     throw new FileNotFoundException(msg);
267                 }
268                 if (!f.isDirectory()) {
269                     isValid = false;
270                     final String msg = String.format("Invalid '%s' argument: '%s' - path does not exist", argumentName, path);
271                     throw new FileNotFoundException(msg);
272                 }
273             } else if (!f.exists()) {
274                 isValid = false;
275                 final String msg = String.format("Invalid '%s' argument: '%s' - path does not exist", argumentName, path);
276                 throw new FileNotFoundException(msg);
277             }
278 //        } else if (path.startsWith("//") || path.startsWith("\\\\")) {
279 //            isValid = false;
280 //            final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path);
281 //            throw new FileNotFoundException(msg);
282         } else if ((path.endsWith("/*") && !path.endsWith("**/*")) || (path.endsWith("\\*") && path.endsWith("**\\*"))) {
283             LOGGER.warn("Possibly incorrect path '{}' from argument '{}' because it ends with a slash star; "
284                     + "dependency-check uses ant-style paths", path, argumentName);
285         }
286     }
287 
288     /**
289      * Generates an Options collection that is used to parse the command line
290      * and to display the help message.
291      *
292      * @return the command line options used for parsing the command line
293      */
294     @SuppressWarnings("static-access")
295     private Options createCommandLineOptions() {
296         final Options options = new Options();
297         addStandardOptions(options);
298         addAdvancedOptions(options);
299         addDeprecatedOptions(options);
300         return options;
301     }
302 
303     /**
304      * Adds the standard command line options to the given options collection.
305      *
306      * @param options a collection of command line arguments
307      */
308     @SuppressWarnings("static-access")
309     private void addStandardOptions(final Options options) {
310         //This is an option group because it can be specified more then once.
311 
312         options.addOptionGroup(newOptionGroup(newOptionWithArg(ARGUMENT.SCAN_SHORT, ARGUMENT.SCAN, "path",
313                 "The path to scan - this option can be specified multiple times. Ant style paths are supported (e.g. 'path/**/*.jar'); "
314                 + "if using Ant style paths it is highly recommended to quote the argument value.")))
315                 .addOptionGroup(newOptionGroup(newOptionWithArg(ARGUMENT.EXCLUDE, "pattern", "Specify an exclusion pattern. This option "
316                         + "can be specified multiple times and it accepts Ant style exclusions.")))
317                 .addOption(newOptionWithArg(ARGUMENT.PROJECT, "name", "The name of the project being scanned."))
318                 .addOption(newOptionWithArg(ARGUMENT.OUT_SHORT, ARGUMENT.OUT, "path",
319                         "The folder to write reports to. This defaults to the current directory. It is possible to set this to a specific "
320                         + "file name if the format argument is not set to ALL."))
321                 .addOption(newOptionWithArg(ARGUMENT.OUTPUT_FORMAT_SHORT, ARGUMENT.OUTPUT_FORMAT, "format",
322                         "The report format (" + SUPPORTED_FORMATS + "). The default is HTML. Multiple format parameters can be specified."))
323                 .addOption(newOption(ARGUMENT.PRETTY_PRINT, "When specified the JSON and XML report formats will be pretty printed."))
324                 .addOption(newOption(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION, "Print the version information."))
325                 .addOption(newOption(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, "Print this message."))
326                 .addOption(newOption(ARGUMENT.ADVANCED_HELP, "Print the advanced help message."))
327                 .addOption(newOption(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE,
328                         "Disables the automatic updating of the NVD-CVE, hosted-suppressions and RetireJS data."))
329                 .addOption(newOptionWithArg(ARGUMENT.VERBOSE_LOG_SHORT, ARGUMENT.VERBOSE_LOG, "file",
330                         "The file path to write verbose logging information."))
331                 .addOptionGroup(newOptionGroup(newOptionWithArg(ARGUMENT.SUPPRESSION_FILES, "file",
332                         "The file path to the suppression XML file. This can be specified more then once to utilize multiple suppression files")))
333                 .addOption(newOption(ARGUMENT.EXPERIMENTAL, "Enables the experimental analyzers."))
334                 .addOption(newOptionWithArg(ARGUMENT.NVD_API_KEY, "apiKey", "The API Key to access the NVD API."))
335                 .addOption(newOptionWithArg(ARGUMENT.FAIL_ON_CVSS, "score",
336                         "Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11; "
337                         + "since the CVSS scores are 0-10, by default the build will never fail."))
338                 .addOption(newOptionWithArg(ARGUMENT.FAIL_JUNIT_ON_CVSS, "score",
339                         "Specifies the CVSS score that is considered a failure when generating the junit report. The default is 0."));
340     }
341 
342     /**
343      * Adds the advanced command line options to the given options collection.
344      * These are split out for purposes of being able to display two different
345      * help messages.
346      *
347      * @param options a collection of command line arguments
348      */
349     @SuppressWarnings("static-access")
350     private void addAdvancedOptions(final Options options) {
351         options
352                 .addOption(newOption(ARGUMENT.UPDATE_ONLY,
353                         "Only update the local NVD data cache; no scan will be executed."))
354                 .addOption(newOptionWithArg(ARGUMENT.NVD_API_DELAY, "milliseconds",
355                         "Time in milliseconds to wait between downloading from the NVD."))
356                 .addOption(newOptionWithArg(ARGUMENT.NVD_API_ENDPOINT, "endpoint",
357                         "The NVD API Endpoint - setting this is rare."))
358                 .addOption(newOptionWithArg(ARGUMENT.NVD_API_DATAFEED_URL, "url",
359                         "The URL to the NVD API Datafeed."))
360                 .addOption(newOptionWithArg(ARGUMENT.NVD_API_DATAFEED_USER, "user",
361                         "Credentials for basic authentication to the NVD API Datafeed."))
362                 .addOption(newOptionWithArg(ARGUMENT.NVD_API_DATAFEED_PASSWORD, "password",
363                         "Credentials for basic authentication to the NVD API Datafeed."))
364                 .addOption(newOptionWithArg(ARGUMENT.NVD_API_MAX_RETRY_COUNT,"count",
365                         "The maximum number of retry requests for a single call to the NVD API."))
366                 .addOption(newOptionWithArg(ARGUMENT.NVD_API_VALID_FOR_HOURS, "hours",
367                         "The number of hours to wait before checking for new updates from the NVD."))
368                 .addOption(newOptionWithArg(ARGUMENT.PROXY_PORT, "port",
369                         "The proxy port to use when downloading resources."))
370                 .addOption(newOptionWithArg(ARGUMENT.PROXY_SERVER, "server",
371                         "The proxy server to use when downloading resources."))
372                 .addOption(newOptionWithArg(ARGUMENT.PROXY_USERNAME, "user",
373                         "The proxy username to use when downloading resources."))
374                 .addOption(newOptionWithArg(ARGUMENT.PROXY_PASSWORD, "pass",
375                         "The proxy password to use when downloading resources."))
376                 .addOption(newOptionWithArg(ARGUMENT.NON_PROXY_HOSTS, "list",
377                         "The proxy exclusion list: hostnames (or patterns) for which proxy should not be used. "
378                         + "Use pipe, comma or colon as list separator."))
379                 .addOption(newOptionWithArg(ARGUMENT.CONNECTION_TIMEOUT_SHORT, ARGUMENT.CONNECTION_TIMEOUT, "timeout",
380                         "The connection timeout (in milliseconds) to use when downloading resources."))
381                 .addOption(newOptionWithArg(ARGUMENT.CONNECTION_READ_TIMEOUT, "timeout",
382                         "The read timeout (in milliseconds) to use when downloading resources."))
383                 .addOption(newOptionWithArg(ARGUMENT.CONNECTION_STRING, "connStr",
384                         "The connection string to the database."))
385                 .addOption(newOptionWithArg(ARGUMENT.DB_NAME, "user",
386                         "The username used to connect to the database."))
387                 .addOption(newOptionWithArg(ARGUMENT.DATA_DIRECTORY_SHORT, ARGUMENT.DATA_DIRECTORY, "path",
388                         "The location of the H2 Database file. This option should generally not be set."))
389                 .addOption(newOptionWithArg(ARGUMENT.DB_PASSWORD, "password",
390                         "The password for connecting to the database."))
391                 .addOption(newOptionWithArg(ARGUMENT.DB_DRIVER, "driver",
392                         "The database driver name."))
393                 .addOption(newOptionWithArg(ARGUMENT.DB_DRIVER_PATH, "path",
394                         "The path to the database driver; note, this does not need to be set unless the JAR is "
395                         + "outside of the classpath."))
396                 .addOption(newOptionWithArg(ARGUMENT.SYM_LINK_DEPTH, "depth",
397                         "Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed."))
398                 .addOption(newOptionWithArg(ARGUMENT.PATH_TO_BUNDLE_AUDIT, "path",
399                         "The path to bundle-audit for Gem bundle analysis."))
400                 .addOption(newOptionWithArg(ARGUMENT.PATH_TO_BUNDLE_AUDIT_WORKING_DIRECTORY, "path",
401                         "The path to working directory that the bundle-audit command should be executed from when "
402                         + "doing Gem bundle analysis."))
403                 .addOption(newOptionWithArg(ARGUMENT.CENTRAL_URL, "url",
404                         "Alternative URL for Maven Central Search. If not set the public Sonatype Maven Central will be used."))
405                 .addOption(newOptionWithArg(ARGUMENT.OSSINDEX_URL, "url",
406                         "Alternative URL for the OSS Index. If not set the public Sonatype OSS Index will be used."))
407                 .addOption(newOptionWithArg(ARGUMENT.OSSINDEX_USERNAME, "username",
408                         "The username to authenticate to Sonatype's OSS Index. If not set the Sonatype OSS Index "
409                         + "Analyzer will use an unauthenticated connection."))
410                 .addOption(newOptionWithArg(ARGUMENT.OSSINDEX_PASSWORD, "password", ""
411                         + "The password to authenticate to Sonatype's OSS Index. If not set the Sonatype OSS "
412                         + "Index Analyzer will use an unauthenticated connection."))
413                 .addOption(newOptionWithArg(ARGUMENT.OSSINDEX_WARN_ONLY_ON_REMOTE_ERRORS, "true/false", ""
414                         + "Whether a Sonatype OSS Index remote error should result in a warning only or a failure."))
415                 .addOption(newOption(ARGUMENT.RETIRE_JS_FORCEUPDATE, "Force the RetireJS Analyzer to update "
416                         + "even if autoupdate is disabled"))
417                 .addOption(newOptionWithArg(ARGUMENT.RETIREJS_URL, "url",
418                         "The Retire JS Repository URL"))
419                 .addOption(newOptionWithArg(ARGUMENT.RETIREJS_URL_USER, "username",
420                         "The password to authenticate to Retire JS Repository URL"))
421                 .addOption(newOptionWithArg(ARGUMENT.RETIREJS_URL_PASSWORD, "password",
422                         "The password to authenticate to Retire JS Repository URL"))
423                 .addOption(newOption(ARGUMENT.RETIREJS_FILTER_NON_VULNERABLE, "Specifies that the Retire JS "
424                         + "Analyzer should filter out non-vulnerable JS files from the report."))
425                 .addOption(newOptionWithArg(ARGUMENT.ARTIFACTORY_PARALLEL_ANALYSIS, "true/false",
426                         "Whether the Artifactory Analyzer should use parallel analysis."))
427                 .addOption(newOptionWithArg(ARGUMENT.ARTIFACTORY_USES_PROXY, "true/false",
428                         "Whether the Artifactory Analyzer should use the proxy."))
429                 .addOption(newOptionWithArg(ARGUMENT.ARTIFACTORY_USERNAME, "username",
430                         "The Artifactory username for authentication."))
431                 .addOption(newOptionWithArg(ARGUMENT.ARTIFACTORY_API_TOKEN, "token",
432                         "The Artifactory API token."))
433                 .addOption(newOptionWithArg(ARGUMENT.ARTIFACTORY_BEARER_TOKEN, "token",
434                         "The Artifactory bearer token."))
435                 .addOption(newOptionWithArg(ARGUMENT.ARTIFACTORY_URL, "url",
436                         "The Artifactory URL."))
437                 .addOption(newOptionWithArg(ARGUMENT.PATH_TO_GO, "path",
438                         "The path to the `go` executable."))
439                 .addOption(newOptionWithArg(ARGUMENT.PATH_TO_YARN, "path",
440                         "The path to the `yarn` executable."))
441                 .addOption(newOptionWithArg(ARGUMENT.PATH_TO_PNPM, "path",
442                         "The path to the `pnpm` executable."))
443                 .addOption(newOptionWithArg(ARGUMENT.RETIREJS_FILTERS, "pattern",
444                         "Specify Retire JS content filter used to exclude files from analysis based on their content; "
445                         + "most commonly used to exclude based on your applications own copyright line. This "
446                         + "option can be specified multiple times."))
447                 .addOption(newOptionWithArg(ARGUMENT.NEXUS_URL, "url",
448                         "The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). If not "
449                         + "set the Nexus Analyzer will be disabled."))
450                 .addOption(newOptionWithArg(ARGUMENT.NEXUS_USERNAME, "username",
451                         "The username to authenticate to the Nexus Server's REST API Endpoint. If not set the Nexus "
452                         + "Analyzer will use an unauthenticated connection."))
453                 .addOption(newOptionWithArg(ARGUMENT.NEXUS_PASSWORD, "password",
454                         "The password to authenticate to the Nexus Server's REST API Endpoint. If not set the Nexus "
455                         + "Analyzer will use an unauthenticated connection."))
456                 //TODO remove as this should be covered by non-proxy hosts
457                 .addOption(newOptionWithArg(ARGUMENT.NEXUS_USES_PROXY, "true/false",
458                         "Whether or not the configured proxy should be used when connecting to Nexus."))
459                 .addOption(newOptionWithArg(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS, "extensions",
460                         "A comma separated list of additional extensions to be scanned as ZIP files (ZIP, EAR, WAR "
461                         + "are already treated as zip files)"))
462                 .addOption(newOptionWithArg(ARGUMENT.PROP_SHORT, ARGUMENT.PROP, "file", "A property file to load."))
463                 .addOption(newOptionWithArg(ARGUMENT.PATH_TO_CORE, "path", "The path to dotnet core."))
464                 .addOption(newOptionWithArg(ARGUMENT.HINTS_FILE, "file", "The file path to the hints XML file."))
465                 .addOption(newOption(ARGUMENT.RETIRED, "Enables the retired analyzers."))
466                 .addOption(newOption(ARGUMENT.DISABLE_MSBUILD, "Disable the MS Build Analyzer."))
467                 .addOption(newOption(ARGUMENT.DISABLE_JAR, "Disable the Jar Analyzer."))
468                 .addOption(newOption(ARGUMENT.DISABLE_ARCHIVE, "Disable the Archive Analyzer."))
469                 .addOption(newOption(ARGUMENT.DISABLE_KEV, "Disable the Known Exploited Vulnerability Analyzer."))
470                 .addOption(newOptionWithArg(ARGUMENT.KEV_URL, "url", "The url to the CISA Known Exploited Vulnerabilities JSON data feed"))
471                 .addOption(newOption(ARGUMENT.DISABLE_ASSEMBLY, "Disable the .NET Assembly Analyzer."))
472                 .addOption(newOption(ARGUMENT.DISABLE_PY_DIST, "Disable the Python Distribution Analyzer."))
473                 .addOption(newOption(ARGUMENT.DISABLE_CMAKE, "Disable the Cmake Analyzer."))
474                 .addOption(newOption(ARGUMENT.DISABLE_PY_PKG, "Disable the Python Package Analyzer."))
475                 .addOption(newOption(ARGUMENT.DISABLE_MIX_AUDIT, "Disable the Elixir mix_audit Analyzer."))
476                 .addOption(newOption(ARGUMENT.DISABLE_RUBYGEMS, "Disable the Ruby Gemspec Analyzer."))
477                 .addOption(newOption(ARGUMENT.DISABLE_BUNDLE_AUDIT, "Disable the Ruby Bundler-Audit Analyzer."))
478                 .addOption(newOption(ARGUMENT.DISABLE_FILENAME, "Disable the File Name Analyzer."))
479                 .addOption(newOption(ARGUMENT.DISABLE_AUTOCONF, "Disable the Autoconf Analyzer."))
480                 .addOption(newOption(ARGUMENT.DISABLE_MAVEN_INSTALL, "Disable the Maven install Analyzer."))
481                 .addOption(newOption(ARGUMENT.DISABLE_PIP, "Disable the pip Analyzer."))
482                 .addOption(newOption(ARGUMENT.DISABLE_PIPFILE, "Disable the Pipfile Analyzer."))
483                 .addOption(newOption(ARGUMENT.DISABLE_COMPOSER, "Disable the PHP Composer Analyzer."))
484                 .addOption(newOption(ARGUMENT.DISABLE_CPAN, "Disable the Perl CPAN file Analyzer."))
485                 .addOption(newOption(ARGUMENT.DISABLE_POETRY, "Disable the Poetry Analyzer."))
486                 .addOption(newOption(ARGUMENT.DISABLE_GOLANG_MOD, "Disable the Golang Mod Analyzer."))
487                 .addOption(newOption(ARGUMENT.DISABLE_DART, "Disable the Dart Analyzer."))
488                 .addOption(newOption(ARGUMENT.DISABLE_OPENSSL, "Disable the OpenSSL Analyzer."))
489                 .addOption(newOption(ARGUMENT.DISABLE_NUSPEC, "Disable the Nuspec Analyzer."))
490                 .addOption(newOption(ARGUMENT.DISABLE_NUGETCONF, "Disable the Nuget packages.config Analyzer."))
491                 .addOption(newOption(ARGUMENT.DISABLE_CENTRAL, "Disable the Central Analyzer. If this analyzer "
492                         + "is disabled it is likely you also want to disable the Nexus Analyzer."))
493                 .addOption(newOption(ARGUMENT.DISABLE_CENTRAL_CACHE, "Disallow the Central Analyzer from caching results"))
494                 .addOption(newOption(ARGUMENT.DISABLE_OSSINDEX, "Disable the Sonatype OSS Index Analyzer."))
495                 .addOption(newOption(ARGUMENT.DISABLE_OSSINDEX_CACHE, "Disallow the OSS Index Analyzer from caching results"))
496                 .addOption(newOption(ARGUMENT.DISABLE_COCOAPODS, "Disable the CocoaPods Analyzer."))
497                 .addOption(newOption(ARGUMENT.DISABLE_CARTHAGE, "Disable the Carthage Analyzer."))
498                 .addOption(newOption(ARGUMENT.DISABLE_SWIFT, "Disable the swift package Analyzer."))
499                 .addOption(newOption(ARGUMENT.DISABLE_SWIFT_RESOLVED, "Disable the swift package resolved Analyzer."))
500                 .addOption(newOption(ARGUMENT.DISABLE_GO_DEP, "Disable the Golang Package Analyzer."))
501                 .addOption(newOption(ARGUMENT.DISABLE_NODE_JS, "Disable the Node.js Package Analyzer."))
502                 .addOption(newOption(ARGUMENT.NODE_PACKAGE_SKIP_DEV_DEPENDENCIES, "Configures the Node Package Analyzer to skip devDependencies"))
503                 .addOption(newOption(ARGUMENT.DISABLE_NODE_AUDIT, "Disable the Node Audit Analyzer."))
504                 .addOption(newOption(ARGUMENT.DISABLE_PNPM_AUDIT, "Disable the Pnpm Audit Analyzer."))
505                 .addOption(newOption(ARGUMENT.DISABLE_YARN_AUDIT, "Disable the Yarn Audit Analyzer."))
506                 .addOption(newOption(ARGUMENT.DISABLE_NODE_AUDIT_CACHE, "Disallow the Node Audit Analyzer from caching results"))
507                 .addOption(newOption(ARGUMENT.DISABLE_NODE_AUDIT_SKIPDEV, "Configures the Node Audit Analyzer to skip devDependencies"))
508                 .addOption(newOption(ARGUMENT.DISABLE_RETIRE_JS, "Disable the RetireJS Analyzer."))
509                 .addOption(newOption(ARGUMENT.ENABLE_NEXUS, "Enable the Nexus Analyzer."))
510                 .addOption(newOption(ARGUMENT.ARTIFACTORY_ENABLED, "Whether the Artifactory Analyzer should be enabled."))
511                 .addOption(newOption(ARGUMENT.PURGE_NVD, "Purges the local NVD data cache"))
512                 .addOption(newOption(ARGUMENT.DISABLE_HOSTED_SUPPRESSIONS, "Disable the usage of the hosted suppressions file"))
513                 .addOption(newOption(ARGUMENT.HOSTED_SUPPRESSIONS_FORCEUPDATE, "Force the hosted suppressions file to update even"
514                         + " if autoupdate is disabled"))
515                 .addOption(newOptionWithArg(ARGUMENT.HOSTED_SUPPRESSIONS_VALID_FOR_HOURS, "hours",
516                         "The number of hours to wait before checking for new updates of the the hosted suppressions file."))
517                 .addOption(newOptionWithArg(ARGUMENT.HOSTED_SUPPRESSIONS_URL, "url",
518                         "The URL for a mirrored hosted suppressions file"));
519 
520     }
521 
522     /**
523      * Adds the deprecated command line options to the given options collection.
524      * These are split out for purposes of not including them in the help
525      * message. We need to add the deprecated options so as not to break
526      * existing scripts.
527      *
528      * @param options a collection of command line arguments
529      */
530     @SuppressWarnings({"static-access", "deprecation"})
531     private void addDeprecatedOptions(final Options options) {
532         //not a real option - but enables java debugging via the shell script
533         options.addOption(newOption("debug",
534                 "Used to enable java debugging of the cli via dependency-check.sh."));
535     }
536 
537     /**
538      * Determines if the 'version' command line argument was passed in.
539      *
540      * @return whether or not the 'version' command line argument was passed in
541      */
542     public boolean isGetVersion() {
543         return (line != null) && line.hasOption(ARGUMENT.VERSION);
544     }
545 
546     /**
547      * Determines if the 'help' command line argument was passed in.
548      *
549      * @return whether or not the 'help' command line argument was passed in
550      */
551     public boolean isGetHelp() {
552         return (line != null) && line.hasOption(ARGUMENT.HELP);
553     }
554 
555     /**
556      * Determines if the 'scan' command line argument was passed in.
557      *
558      * @return whether or not the 'scan' command line argument was passed in
559      */
560     public boolean isRunScan() {
561         return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN);
562     }
563 
564     /**
565      * Returns the symbolic link depth (how deeply symbolic links will be
566      * followed).
567      *
568      * @return the symbolic link depth
569      */
570     public int getSymLinkDepth() {
571         int value = 0;
572         try {
573             value = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH, "0"));
574             if (value < 0) {
575                 value = 0;
576             }
577         } catch (NumberFormatException ex) {
578             LOGGER.debug("Symbolic link was not a number");
579         }
580         return value;
581     }
582 
583     /**
584      * Utility method to determine if one of the disable options has been set.
585      * If not set, this method will check the currently configured settings for
586      * the current value to return.
587      * <p>
588      * Example given `--disableArchive` on the command line would cause this
589      * method to return true for the disable archive setting.
590      *
591      * @param disableFlag the command line disable option
592      * @param setting the corresponding settings key
593      * @return true if the disable option was set, if not set the currently
594      * configured value will be returned
595      */
596     public boolean isDisabled(String disableFlag, String setting) {
597         if (line == null || !line.hasOption(disableFlag)) {
598             try {
599                 return !settings.getBoolean(setting);
600             } catch (InvalidSettingException ise) {
601                 LOGGER.warn("Invalid property setting '{}' defaulting to false", setting);
602                 return false;
603             }
604         } else {
605             return true;
606         }
607     }
608 
609     /**
610      * Returns true if the disableNodeAudit command line argument was specified.
611      *
612      * @return true if the disableNodeAudit command line argument was specified;
613      * otherwise false
614      */
615     public boolean isNodeAuditDisabled() {
616         return isDisabled(ARGUMENT.DISABLE_NODE_AUDIT, Settings.KEYS.ANALYZER_NODE_AUDIT_ENABLED);
617     }
618 
619     /**
620      * Returns true if the disableYarnAudit command line argument was specified.
621      *
622      * @return true if the disableYarnAudit command line argument was specified;
623      * otherwise false
624      */
625     public boolean isYarnAuditDisabled() {
626         return isDisabled(ARGUMENT.DISABLE_YARN_AUDIT, Settings.KEYS.ANALYZER_YARN_AUDIT_ENABLED);
627     }
628 
629     /**
630      * Returns true if the disablePnpmAudit command line argument was specified.
631      *
632      * @return true if the disablePnpmAudit command line argument was specified;
633      * otherwise false
634      */
635     public boolean isPnpmAuditDisabled() {
636         return isDisabled(ARGUMENT.DISABLE_PNPM_AUDIT, Settings.KEYS.ANALYZER_PNPM_AUDIT_ENABLED);
637     }
638 
639     /**
640      * Returns true if the Nexus Analyzer should use the configured proxy to
641      * connect to Nexus; otherwise false is returned.
642      *
643      * @return true if the Nexus Analyzer should use the configured proxy to
644      * connect to Nexus; otherwise false
645      */
646     public boolean isNexusUsesProxy() {
647         // If they didn't specify whether Nexus needs to use the proxy, we should
648         // still honor the property if it's set.
649         if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) {
650             try {
651                 return settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY);
652             } catch (InvalidSettingException ise) {
653                 return true;
654             }
655         } else {
656             return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY));
657         }
658     }
659 
660     /**
661      * Returns the argument boolean value.
662      *
663      * @param argument the argument
664      * @return the argument boolean value
665      */
666     @SuppressFBWarnings(justification = "Accepting that this is a bad practice - used a Boolean as we needed three states",
667             value = {"NP_BOOLEAN_RETURN_NULL"})
668     public Boolean getBooleanArgument(String argument) {
669         if (line != null && line.hasOption(argument)) {
670             final String value = line.getOptionValue(argument);
671             if (value != null) {
672                 return Boolean.parseBoolean(value);
673             }
674         }
675         return null;
676     }
677 
678     /**
679      * Returns the argument value for the given option.
680      *
681      * @param option the option
682      * @return the value of the argument
683      */
684     public String getStringArgument(String option) {
685         return getStringArgument(option, null);
686     }
687 
688     /**
689      * Returns the argument value for the given option.
690      *
691      * @param option the option
692      * @param key the dependency-check settings key for the option.
693      * @return the value of the argument
694      */
695     public String getStringArgument(String option, String key) {
696         if (line != null && line.hasOption(option)) {
697             if (key != null && (option.toLowerCase().endsWith("password")
698                     || option.toLowerCase().endsWith("pass"))) {
699                 LOGGER.warn("{} used on the command line, consider moving the password "
700                         + "to a properties file using the key `{}` and using the "
701                         + "--propertyfile argument instead", option, key);
702             }
703             return line.getOptionValue(option);
704         }
705         return null;
706     }
707 
708     /**
709      * Returns the argument value for the given option.
710      *
711      * @param option the option
712      * @return the value of the argument
713      */
714     public String[] getStringArguments(String option) {
715         if (line != null && line.hasOption(option)) {
716             return line.getOptionValues(option);
717         }
718         return null;
719     }
720 
721     /**
722      * Returns the argument value for the given option.
723      *
724      * @param option the option
725      * @return the value of the argument
726      */
727     public File getFileArgument(String option) {
728         final String path = line.getOptionValue(option);
729         if (path != null) {
730             return new File(path);
731         }
732         return null;
733     }
734 
735     /**
736      * Displays the command line help message to the standard output.
737      */
738     public void printHelp() {
739         final HelpFormatter formatter = new HelpFormatter();
740         final Options options = new Options();
741         addStandardOptions(options);
742         if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) {
743             addAdvancedOptions(options);
744         }
745         final String helpMsg = String.format("%n%s"
746                 + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. "
747                 + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n",
748                 settings.getString(Settings.KEYS.APPLICATION_NAME, "DependencyCheck"),
749                 settings.getString(Settings.KEYS.APPLICATION_NAME, "DependencyCheck"));
750 
751         formatter.printHelp(settings.getString(Settings.KEYS.APPLICATION_NAME, "DependencyCheck"),
752                 helpMsg,
753                 options,
754                 "",
755                 true);
756     }
757 
758     /**
759      * Retrieves the file command line parameter(s) specified for the 'scan'
760      * argument.
761      *
762      * @return the file paths specified on the command line for scan
763      */
764     public String[] getScanFiles() {
765         return line.getOptionValues(ARGUMENT.SCAN);
766     }
767 
768     /**
769      * Retrieves the list of excluded file patterns specified by the 'exclude'
770      * argument.
771      *
772      * @return the excluded file patterns
773      */
774     public String[] getExcludeList() {
775         return line.getOptionValues(ARGUMENT.EXCLUDE);
776     }
777 
778     /**
779      * Retrieves the list of retire JS content filters used to exclude JS files
780      * by content.
781      *
782      * @return the retireJS filters
783      */
784     public String[] getRetireJsFilters() {
785         return line.getOptionValues(ARGUMENT.RETIREJS_FILTERS);
786     }
787 
788     /**
789      * Returns whether or not the retireJS analyzer should exclude
790      * non-vulnerable JS from the report.
791      *
792      * @return <code>true</code> if non-vulnerable JS should be filtered in the
793      * RetireJS Analyzer; otherwise <code>null</code>
794      */
795     @SuppressFBWarnings(justification = "Accepting that this is a bad practice - but made more sense in this use case",
796             value = {"NP_BOOLEAN_RETURN_NULL"})
797     public Boolean isRetireJsFilterNonVulnerable() {
798         return (line != null && line.hasOption(ARGUMENT.RETIREJS_FILTER_NON_VULNERABLE)) ? true : null;
799     }
800 
801     /**
802      * Returns the directory to write the reports to specified on the command
803      * line.
804      *
805      * @return the path to the reports directory.
806      */
807     public String getReportDirectory() {
808         return line.getOptionValue(ARGUMENT.OUT, ".");
809     }
810 
811     /**
812      * Returns the output format specified on the command line. Defaults to HTML
813      * if no format was specified.
814      *
815      * @return the output format name.
816      */
817     public String[] getReportFormat() {
818         if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
819             return line.getOptionValues(ARGUMENT.OUTPUT_FORMAT);
820         }
821         return new String[]{"HTML"};
822     }
823 
824     /**
825      * Returns the application name specified on the command line.
826      *
827      * @return the application name.
828      */
829     public String getProjectName() {
830         String name = line.getOptionValue(ARGUMENT.PROJECT);
831         if (name == null) {
832             name = "";
833         }
834         return name;
835     }
836 
837     /**
838      * <p>
839      * Prints the manifest information to standard output.</p>
840      * <ul><li>Implementation-Title: ${pom.name}</li>
841      * <li>Implementation-Version: ${pom.version}</li></ul>
842      */
843     public void printVersionInfo() {
844         final String version = String.format("%s version %s",
845                 settings.getString(Settings.KEYS.APPLICATION_NAME, "dependency-check"),
846                 settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown"));
847         System.out.println(version);
848     }
849 
850     /**
851      * Checks if the update only flag has been set.
852      *
853      * @return <code>true</code> if the update only flag has been set; otherwise
854      * <code>false</code>.
855      */
856     public boolean isUpdateOnly() {
857         return line != null && line.hasOption(ARGUMENT.UPDATE_ONLY);
858     }
859 
860     /**
861      * Checks if the purge NVD flag has been set.
862      *
863      * @return <code>true</code> if the purge nvd flag has been set; otherwise
864      * <code>false</code>.
865      */
866     public boolean isPurge() {
867         return line != null && line.hasOption(ARGUMENT.PURGE_NVD);
868     }
869 
870     /**
871      * Returns the database driver name if specified; otherwise null is
872      * returned.
873      *
874      * @return the database driver name if specified; otherwise null is returned
875      */
876     public String getDatabaseDriverName() {
877         return line.getOptionValue(ARGUMENT.DB_DRIVER);
878     }
879 
880     /**
881      * Returns the argument value.
882      *
883      * @param argument the argument
884      * @return the value of the argument
885      */
886     public Integer getIntegerValue(String argument) {
887         final String v = line.getOptionValue(argument);
888         if (v != null) {
889             return Integer.parseInt(v);
890         }
891         return null;
892     }
893 
894     /**
895      * Checks if the option is present. If present it will return
896      * <code>true</code>; otherwise <code>false</code>.
897      *
898      * @param option the option to check
899      * @return <code>true</code> if auto-update is allowed; otherwise
900      * <code>null</code>
901      */
902     @SuppressFBWarnings(justification = "Accepting that this is a bad practice - but made more sense in this use case",
903             value = {"NP_BOOLEAN_RETURN_NULL"})
904     public Boolean hasOption(String option) {
905         return (line != null && line.hasOption(option)) ? true : null;
906     }
907 
908     /**
909      * Returns the CVSS value to fail on.
910      *
911      * @return 11 if nothing is set. Otherwise it returns the int passed from
912      * the command line arg
913      */
914     public float getFailOnCVSS() {
915         if (line.hasOption(ARGUMENT.FAIL_ON_CVSS)) {
916             final String value = line.getOptionValue(ARGUMENT.FAIL_ON_CVSS);
917             try {
918                 return Float.parseFloat(value);
919             } catch (NumberFormatException nfe) {
920                 return 11;
921             }
922         } else {
923             return 11;
924         }
925     }
926 
927     /**
928      * Returns the float argument for the given option.
929      *
930      * @param option the option
931      * @param defaultValue the value if the option is not present
932      * @return the value of the argument if present; otherwise the defaultValue
933      */
934     public float getFloatArgument(String option, float defaultValue) {
935         if (line.hasOption(option)) {
936             final String value = line.getOptionValue(option);
937             try {
938                 return Integer.parseInt(value);
939             } catch (NumberFormatException nfe) {
940                 return defaultValue;
941             }
942         } else {
943             return defaultValue;
944         }
945     }
946 
947     /**
948      * Builds a new option.
949      *
950      * @param name the long name
951      * @param description the description
952      * @return a new option
953      */
954     private Option newOption(String name, String description) {
955         return Option.builder().longOpt(name).desc(description).build();
956     }
957 
958     /**
959      * Builds a new option.
960      *
961      * @param shortName the short name
962      * @param name the long name
963      * @param description the description
964      * @return a new option
965      */
966     private Option newOption(String shortName, String name, String description) {
967         return Option.builder(shortName).longOpt(name).desc(description).build();
968     }
969 
970     /**
971      * Builds a new option.
972      *
973      * @param name the long name
974      * @param arg the argument name
975      * @param description the description
976      * @return a new option
977      */
978     private Option newOptionWithArg(String name, String arg, String description) {
979         return Option.builder().longOpt(name).argName(arg).hasArg().desc(description).build();
980     }
981 
982     /**
983      * Builds a new option.
984      *
985      * @param shortName the short name
986      * @param name the long name
987      * @param arg the argument name
988      * @param description the description
989      * @return a new option
990      */
991     private Option newOptionWithArg(String shortName, String name, String arg, String description) {
992         return Option.builder(shortName).longOpt(name).argName(arg).hasArg().desc(description).build();
993     }
994 
995     /**
996      * Builds a new option group so that an option can be specified multiple
997      * times on the command line.
998      *
999      * @param option the option to add to the group
1000      * @return a new option group
1001      */
1002     private OptionGroup newOptionGroup(Option option) {
1003         final OptionGroup group = new OptionGroup();
1004         group.addOption(option);
1005         return group;
1006     }
1007 
1008     /**
1009      * A collection of static final strings that represent the possible command
1010      * line arguments.
1011      */
1012     public static class ARGUMENT {
1013 
1014         /**
1015          * The long CLI argument name specifying the directory/file to scan.
1016          */
1017         public static final String SCAN = "scan";
1018         /**
1019          * The short CLI argument name specifying the directory/file to scan.
1020          */
1021         public static final String SCAN_SHORT = "s";
1022         /**
1023          * The long CLI argument name specifying that the CPE/CVE/etc. data
1024          * should not be automatically updated.
1025          */
1026         public static final String DISABLE_AUTO_UPDATE = "noupdate";
1027         /**
1028          * The short CLI argument name specifying that the CPE/CVE/etc. data
1029          * should not be automatically updated.
1030          */
1031         public static final String DISABLE_AUTO_UPDATE_SHORT = "n";
1032         /**
1033          * The long CLI argument name specifying that only the update phase
1034          * should be executed; no scan should be run.
1035          */
1036         public static final String UPDATE_ONLY = "updateonly";
1037         /**
1038          * The long CLI argument name specifying that only the update phase
1039          * should be executed; no scan should be run.
1040          */
1041         public static final String PURGE_NVD = "purge";
1042         /**
1043          * The long CLI argument name specifying the directory to write the
1044          * reports to.
1045          */
1046         public static final String OUT = "out";
1047         /**
1048          * The short CLI argument name specifying the directory to write the
1049          * reports to.
1050          */
1051         public static final String OUT_SHORT = "o";
1052         /**
1053          * The long CLI argument name specifying the output format to write the
1054          * reports to.
1055          */
1056         public static final String OUTPUT_FORMAT = "format";
1057         /**
1058          * The short CLI argument name specifying the output format to write the
1059          * reports to.
1060          */
1061         public static final String OUTPUT_FORMAT_SHORT = "f";
1062         /**
1063          * The long CLI argument name specifying the name of the project to be
1064          * scanned.
1065          */
1066         public static final String PROJECT = "project";
1067         /**
1068          * The long CLI argument name asking for help.
1069          */
1070         public static final String HELP = "help";
1071         /**
1072          * The long CLI argument name asking for advanced help.
1073          */
1074         public static final String ADVANCED_HELP = "advancedHelp";
1075         /**
1076          * The short CLI argument name asking for help.
1077          */
1078         public static final String HELP_SHORT = "h";
1079         /**
1080          * The long CLI argument name asking for the version.
1081          */
1082         public static final String VERSION_SHORT = "v";
1083         /**
1084          * The short CLI argument name asking for the version.
1085          */
1086         public static final String VERSION = "version";
1087         /**
1088          * The CLI argument name indicating the proxy port.
1089          */
1090         public static final String PROXY_PORT = "proxyport";
1091         /**
1092          * The CLI argument name indicating the proxy server.
1093          */
1094         public static final String PROXY_SERVER = "proxyserver";
1095         /**
1096          * The CLI argument name indicating the proxy username.
1097          */
1098         public static final String PROXY_USERNAME = "proxyuser";
1099         /**
1100          * The CLI argument name indicating the proxy password.
1101          */
1102         public static final String PROXY_PASSWORD = "proxypass";
1103         /**
1104          * The CLI argument name indicating the proxy proxy exclusion list.
1105          */
1106         public static final String NON_PROXY_HOSTS = "nonProxyHosts";
1107         /**
1108          * The short CLI argument name indicating the connection timeout.
1109          */
1110         public static final String CONNECTION_TIMEOUT_SHORT = "c";
1111         /**
1112          * The CLI argument name indicating the connection timeout.
1113          */
1114         public static final String CONNECTION_TIMEOUT = "connectiontimeout";
1115         /**
1116          * The CLI argument name indicating the connection read timeout.
1117          */
1118         public static final String CONNECTION_READ_TIMEOUT = "readtimeout";
1119         /**
1120          * The short CLI argument name for setting the location of an additional
1121          * properties file.
1122          */
1123         public static final String PROP_SHORT = "P";
1124         /**
1125          * The CLI argument name for setting the location of an additional
1126          * properties file.
1127          */
1128         public static final String PROP = "propertyfile";
1129         /**
1130          * The CLI argument name for setting the location of the data directory.
1131          */
1132         public static final String DATA_DIRECTORY = "data";
1133         /**
1134          * The CLI argument name for setting the URL for the NVD API Endpoint
1135          */
1136         public static final String NVD_API_ENDPOINT = "nvdApiEndpoint";
1137         /**
1138          * The CLI argument name for setting the URL for the NVD API Key.
1139          */
1140         public static final String NVD_API_KEY = "nvdApiKey";
1141         /**
1142         * The CLI argument name for setting the maximum number of retry requests for a single call to the NVD API.
1143         */
1144         public static final String NVD_API_MAX_RETRY_COUNT = "nvdMaxRetryCount";
1145         /**
1146          * The CLI argument name for setting the number of hours to wait before
1147          * checking for new updates from the NVD.
1148          */
1149         public static final String NVD_API_VALID_FOR_HOURS = "nvdValidForHours";
1150         /**
1151          * The CLI argument name for the NVD API Data Feed URL.
1152          */
1153         public static final String NVD_API_DATAFEED_URL = "nvdDatafeed";
1154         /**
1155          * The username for basic auth to the CVE data.
1156          */
1157         public static final String NVD_API_DATAFEED_USER = "nvdUser";
1158         /**
1159          * The password for basic auth to the CVE data.
1160          */
1161         public static final String NVD_API_DATAFEED_PASSWORD = "nvdPassword";
1162         /**
1163          * The time in milliseconds to wait between downloading NVD API data.
1164          */
1165         public static final String NVD_API_DELAY = "nvdApiDelay";
1166         /**
1167          * The short CLI argument name for setting the location of the data
1168          * directory.
1169          */
1170         public static final String DATA_DIRECTORY_SHORT = "d";
1171         /**
1172          * The CLI argument name for setting the location of the data directory.
1173          */
1174         public static final String VERBOSE_LOG = "log";
1175         /**
1176          * The short CLI argument name for setting the location of the data
1177          * directory.
1178          */
1179         public static final String VERBOSE_LOG_SHORT = "l";
1180         /**
1181          * The CLI argument name for setting the depth of symbolic links that
1182          * will be followed.
1183          */
1184         public static final String SYM_LINK_DEPTH = "symLink";
1185         /**
1186          * The CLI argument name for setting the location of the suppression
1187          * file(s).
1188          */
1189         public static final String SUPPRESSION_FILES = "suppression";
1190         /**
1191          * The CLI argument name for setting the location of the hint file.
1192          */
1193         public static final String HINTS_FILE = "hints";
1194         /**
1195          * Disables the Jar Analyzer.
1196          */
1197         public static final String DISABLE_JAR = "disableJar";
1198         /**
1199          * Disable the MS Build Analyzer.
1200          */
1201         public static final String DISABLE_MSBUILD = "disableMSBuild";
1202         /**
1203          * Disables the Archive Analyzer.
1204          */
1205         public static final String DISABLE_ARCHIVE = "disableArchive";
1206         /**
1207          * Disables the Known Exploited Analyzer.
1208          */
1209         public static final String DISABLE_KEV = "disableKnownExploited";
1210         /**
1211          * The URL to the CISA Known Exploited Vulnerability JSON datafeed.
1212          */
1213         public static final String KEV_URL = "kevURL";
1214         /**
1215          * Disables the Python Distribution Analyzer.
1216          */
1217         public static final String DISABLE_PY_DIST = "disablePyDist";
1218         /**
1219          * Disables the Python Package Analyzer.
1220          */
1221         public static final String DISABLE_PY_PKG = "disablePyPkg";
1222         /**
1223          * Disables the Elixir mix audit Analyzer.
1224          */
1225         public static final String DISABLE_MIX_AUDIT = "disableMixAudit";
1226         /**
1227          * Disables the Golang Dependency Analyzer.
1228          */
1229         public static final String DISABLE_GO_DEP = "disableGolangDep";
1230         /**
1231          * Disables the PHP Composer Analyzer.
1232          */
1233         public static final String DISABLE_COMPOSER = "disableComposer";
1234         /**
1235          * Disables the Perl CPAN File Analyzer.
1236          */
1237         public static final String DISABLE_CPAN = "disableCpan";
1238         /**
1239          * Disables the Golang Mod Analyzer.
1240          */
1241         public static final String DISABLE_GOLANG_MOD = "disableGolangMod";
1242         /**
1243          * Disables the Dart Analyzer.
1244          */
1245         public static final String DISABLE_DART = "disableDart";
1246         /**
1247          * The CLI argument name for setting the path to `go`.
1248          */
1249         public static final String PATH_TO_GO = "go";
1250         /**
1251          * The CLI argument name for setting the path to `yarn`.
1252          */
1253         public static final String PATH_TO_YARN = "yarn";
1254         /**
1255          * The CLI argument name for setting the path to `pnpm`.
1256          */
1257         public static final String PATH_TO_PNPM = "pnpm";
1258         /**
1259          * Disables the Ruby Gemspec Analyzer.
1260          */
1261         public static final String DISABLE_RUBYGEMS = "disableRubygems";
1262         /**
1263          * Disables the Autoconf Analyzer.
1264          */
1265         public static final String DISABLE_AUTOCONF = "disableAutoconf";
1266         /**
1267          * Disables the Maven install Analyzer.
1268          */
1269         public static final String DISABLE_MAVEN_INSTALL = "disableMavenInstall";
1270         /**
1271          * Disables the pip Analyzer.
1272          */
1273         public static final String DISABLE_PIP = "disablePip";
1274         /**
1275          * Disables the Pipfile Analyzer.
1276          */
1277         public static final String DISABLE_PIPFILE = "disablePipfile";
1278         /**
1279          * Disables the Poetry Analyzer.
1280          */
1281         public static final String DISABLE_POETRY = "disablePoetry";
1282         /**
1283          * Disables the Cmake Analyzer.
1284          */
1285         public static final String DISABLE_CMAKE = "disableCmake";
1286         /**
1287          * Disables the cocoapods analyzer.
1288          */
1289         public static final String DISABLE_COCOAPODS = "disableCocoapodsAnalyzer";
1290         /**
1291          * Disables the Carthage analyzer.
1292          */
1293         public static final String DISABLE_CARTHAGE = "disableCarthageAnalyzer";
1294         /**
1295          * Disables the swift package manager analyzer.
1296          */
1297         public static final String DISABLE_SWIFT = "disableSwiftPackageManagerAnalyzer";
1298         /**
1299          * Disables the swift package resolved analyzer.
1300          */
1301         public static final String DISABLE_SWIFT_RESOLVED = "disableSwiftPackageResolvedAnalyzer";
1302         /**
1303          * Disables the Assembly Analyzer.
1304          */
1305         public static final String DISABLE_ASSEMBLY = "disableAssembly";
1306         /**
1307          * Disables the Ruby Bundler Audit Analyzer.
1308          */
1309         public static final String DISABLE_BUNDLE_AUDIT = "disableBundleAudit";
1310         /**
1311          * Disables the File Name Analyzer.
1312          */
1313         public static final String DISABLE_FILENAME = "disableFileName";
1314         /**
1315          * Disables the Nuspec Analyzer.
1316          */
1317         public static final String DISABLE_NUSPEC = "disableNuspec";
1318         /**
1319          * Disables the Nuget packages.config Analyzer.
1320          */
1321         public static final String DISABLE_NUGETCONF = "disableNugetconf";
1322         /**
1323          * Disables the Central Analyzer.
1324          */
1325         public static final String DISABLE_CENTRAL = "disableCentral";
1326         /**
1327          * Disables the Central Analyzer's ability to cache results locally.
1328          */
1329         public static final String DISABLE_CENTRAL_CACHE = "disableCentralCache";
1330         /**
1331          * The alternative URL for Maven Central Search.
1332          */
1333         public static final String CENTRAL_URL = "centralUrl";
1334         /**
1335          * Disables the Nexus Analyzer.
1336          */
1337         public static final String ENABLE_NEXUS = "enableNexus";
1338         /**
1339          * Disables the Sonatype OSS Index Analyzer.
1340          */
1341         public static final String DISABLE_OSSINDEX = "disableOssIndex";
1342         /**
1343          * Disables the Sonatype OSS Index Analyzer's ability to cache results
1344          * locally.
1345          */
1346         public static final String DISABLE_OSSINDEX_CACHE = "disableOssIndexCache";
1347         /**
1348          * The alternative URL for the Sonatype OSS Index.
1349          */
1350         public static final String OSSINDEX_URL = "ossIndexUrl";
1351         /**
1352          * The username for the Sonatype OSS Index.
1353          */
1354         public static final String OSSINDEX_USERNAME = "ossIndexUsername";
1355         /**
1356          * The password for the Sonatype OSS Index.
1357          */
1358         public static final String OSSINDEX_PASSWORD = "ossIndexPassword";
1359         /**
1360          * The password for the Sonatype OSS Index.
1361          */
1362         public static final String OSSINDEX_WARN_ONLY_ON_REMOTE_ERRORS = "ossIndexRemoteErrorWarnOnly";
1363         /**
1364          * Disables the OpenSSL Analyzer.
1365          */
1366         public static final String DISABLE_OPENSSL = "disableOpenSSL";
1367         /**
1368          * Disables the Node.js Package Analyzer.
1369          */
1370         public static final String DISABLE_NODE_JS = "disableNodeJS";
1371         /**
1372          * Skips dev dependencies in Node Package Analyzer.
1373          */
1374         public static final String NODE_PACKAGE_SKIP_DEV_DEPENDENCIES = "nodePackageSkipDevDependencies";
1375         /**
1376          * Disables the Node Audit Analyzer.
1377          */
1378         public static final String DISABLE_NODE_AUDIT = "disableNodeAudit";
1379         /**
1380          * Disables the Yarn Audit Analyzer.
1381          */
1382         public static final String DISABLE_YARN_AUDIT = "disableYarnAudit";
1383         /**
1384          * Disables the Pnpm Audit Analyzer.
1385          */
1386         public static final String DISABLE_PNPM_AUDIT = "disablePnpmAudit";
1387         /**
1388          * Disables the Node Audit Analyzer's ability to cache results locally.
1389          */
1390         public static final String DISABLE_NODE_AUDIT_CACHE = "disableNodeAuditCache";
1391         /**
1392          * Configures the Node Audit Analyzer to skip the dev dependencies.
1393          */
1394         public static final String DISABLE_NODE_AUDIT_SKIPDEV = "nodeAuditSkipDevDependencies";
1395         /**
1396          * Disables the RetireJS Analyzer.
1397          */
1398         public static final String DISABLE_RETIRE_JS = "disableRetireJS";
1399         /**
1400          * Whether the RetireJS Analyzer will update regardless of the
1401          * `autoupdate` setting.
1402          */
1403         public static final String RETIRE_JS_FORCEUPDATE = "retireJsForceUpdate";
1404         /**
1405          * The URL to the retire JS repository.
1406          */
1407         public static final String RETIREJS_URL = "retireJsUrl";
1408         /**
1409          * The username to the retire JS repository.
1410          */
1411         public static final String RETIREJS_URL_USER = "retireJsUrlUser";
1412         /**
1413          * The password to the retire JS repository.
1414          */
1415         public static final String RETIREJS_URL_PASSWORD = "retireJsUrlPass";
1416         /**
1417          * The URL of the nexus server.
1418          */
1419         public static final String NEXUS_URL = "nexus";
1420         /**
1421          * The username for the nexus server.
1422          */
1423         public static final String NEXUS_USERNAME = "nexusUser";
1424         /**
1425          * The password for the nexus server.
1426          */
1427         public static final String NEXUS_PASSWORD = "nexusPass";
1428         /**
1429          * Whether or not the defined proxy should be used when connecting to
1430          * Nexus.
1431          */
1432         public static final String NEXUS_USES_PROXY = "nexusUsesProxy";
1433         /**
1434          * The CLI argument name for setting the connection string.
1435          */
1436         public static final String CONNECTION_STRING = "connectionString";
1437         /**
1438          * The CLI argument name for setting the database user name.
1439          */
1440         public static final String DB_NAME = "dbUser";
1441         /**
1442          * The CLI argument name for setting the database password.
1443          */
1444         public static final String DB_PASSWORD = "dbPassword";
1445         /**
1446          * The CLI argument name for setting the database driver name.
1447          */
1448         public static final String DB_DRIVER = "dbDriverName";
1449         /**
1450          * The CLI argument name for setting the path to the database driver; in
1451          * case it is not on the class path.
1452          */
1453         public static final String DB_DRIVER_PATH = "dbDriverPath";
1454         /**
1455          * The CLI argument name for setting the path to dotnet core.
1456          */
1457         public static final String PATH_TO_CORE = "dotnet";
1458         /**
1459          * The CLI argument name for setting extra extensions.
1460          */
1461         public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions";
1462         /**
1463          * Exclude path argument.
1464          */
1465         public static final String EXCLUDE = "exclude";
1466         /**
1467          * The CLI argument name for setting the path to bundle-audit for Ruby
1468          * bundle analysis.
1469          */
1470         public static final String PATH_TO_BUNDLE_AUDIT = "bundleAudit";
1471         /**
1472          * The CLI argument name for setting the path that should be used as the
1473          * working directory that the bundle-audit command used for Ruby bundle
1474          * analysis should be executed from. This will allow for the usage of
1475          * rbenv
1476          */
1477         public static final String PATH_TO_BUNDLE_AUDIT_WORKING_DIRECTORY = "bundleAuditWorkingDirectory";
1478         /**
1479          * The CLI argument name for setting the path to mix_audit for Elixir
1480          * analysis.
1481          */
1482         public static final String PATH_TO_MIX_AUDIT = "mixAudit";
1483         /**
1484          * The CLI argument to enable the experimental analyzers.
1485          */
1486         public static final String EXPERIMENTAL = "enableExperimental";
1487         /**
1488          * The CLI argument to enable the retired analyzers.
1489          */
1490         public static final String RETIRED = "enableRetired";
1491         /**
1492          * The CLI argument for the retire js content filters.
1493          */
1494         public static final String RETIREJS_FILTERS = "retirejsFilter";
1495         /**
1496          * The CLI argument for the retire js content filters.
1497          */
1498         public static final String RETIREJS_FILTER_NON_VULNERABLE = "retirejsFilterNonVulnerable";
1499         /**
1500          * The CLI argument for indicating if the Artifactory analyzer should be
1501          * enabled.
1502          */
1503         public static final String ARTIFACTORY_ENABLED = "enableArtifactory";
1504         /**
1505          * The CLI argument for indicating if the Artifactory analyzer should
1506          * use the proxy.
1507          */
1508         public static final String ARTIFACTORY_URL = "artifactoryUrl";
1509         /**
1510          * The CLI argument for indicating the Artifactory username.
1511          */
1512         public static final String ARTIFACTORY_USERNAME = "artifactoryUsername";
1513         /**
1514          * The CLI argument for indicating the Artifactory API token.
1515          */
1516         public static final String ARTIFACTORY_API_TOKEN = "artifactoryApiToken";
1517         /**
1518          * The CLI argument for indicating the Artifactory bearer token.
1519          */
1520         public static final String ARTIFACTORY_BEARER_TOKEN = "artifactoryBearerToken";
1521         /**
1522          * The CLI argument for indicating if the Artifactory analyzer should
1523          * use the proxy.
1524          */
1525         public static final String ARTIFACTORY_USES_PROXY = "artifactoryUseProxy";
1526         /**
1527          * The CLI argument for indicating if the Artifactory analyzer should
1528          * use the parallel analysis.
1529          */
1530         public static final String ARTIFACTORY_PARALLEL_ANALYSIS = "artifactoryParallelAnalysis";
1531         /**
1532          * The CLI argument to configure when the execution should be considered
1533          * a failure.
1534          */
1535         public static final String FAIL_ON_CVSS = "failOnCVSS";
1536         /**
1537          * The CLI argument to configure if the XML and JSON reports should be
1538          * pretty printed.
1539          */
1540         public static final String PRETTY_PRINT = "prettyPrint";
1541         /**
1542          * The CLI argument to set the threshold that is considered a failure
1543          * when generating the JUNIT report format.
1544          */
1545         public static final String FAIL_JUNIT_ON_CVSS = "junitFailOnCVSS";
1546         /**
1547          * The CLI argument to set the number of hours to wait before
1548          * re-checking hosted suppressions file for updates.
1549          */
1550         public static final String DISABLE_HOSTED_SUPPRESSIONS = "disableHostedSuppressions";
1551         /**
1552          * The CLI argument to set the number of hours to wait before
1553          * re-checking hosted suppressions file for updates.
1554          */
1555         public static final String HOSTED_SUPPRESSIONS_VALID_FOR_HOURS = "hostedSuppressionsValidForHours";
1556         /**
1557          * The CLI argument to set Whether the hosted suppressions file will
1558          * update regardless of the `noupdate` argument.
1559          */
1560         public static final String HOSTED_SUPPRESSIONS_FORCEUPDATE = "hostedSuppressionsForceUpdate";
1561         /**
1562          * The CLI argument to set the location of a mirrored hosted
1563          * suppressions file .
1564          */
1565         public static final String HOSTED_SUPPRESSIONS_URL = "hostedSuppressionsUrl";
1566     }
1567 }