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_SWIFT, "Disable the swift package Analyzer."))
498                 .addOption(newOption(ARGUMENT.DISABLE_SWIFT_RESOLVED, "Disable the swift package resolved Analyzer."))
499                 .addOption(newOption(ARGUMENT.DISABLE_GO_DEP, "Disable the Golang Package Analyzer."))
500                 .addOption(newOption(ARGUMENT.DISABLE_NODE_JS, "Disable the Node.js Package Analyzer."))
501                 .addOption(newOption(ARGUMENT.NODE_PACKAGE_SKIP_DEV_DEPENDENCIES, "Configures the Node Package Analyzer to skip devDependencies"))
502                 .addOption(newOption(ARGUMENT.DISABLE_NODE_AUDIT, "Disable the Node Audit Analyzer."))
503                 .addOption(newOption(ARGUMENT.DISABLE_PNPM_AUDIT, "Disable the Pnpm Audit Analyzer."))
504                 .addOption(newOption(ARGUMENT.DISABLE_YARN_AUDIT, "Disable the Yarn Audit Analyzer."))
505                 .addOption(newOption(ARGUMENT.DISABLE_NODE_AUDIT_CACHE, "Disallow the Node Audit Analyzer from caching results"))
506                 .addOption(newOption(ARGUMENT.DISABLE_NODE_AUDIT_SKIPDEV, "Configures the Node Audit Analyzer to skip devDependencies"))
507                 .addOption(newOption(ARGUMENT.DISABLE_RETIRE_JS, "Disable the RetireJS Analyzer."))
508                 .addOption(newOption(ARGUMENT.ENABLE_NEXUS, "Enable the Nexus Analyzer."))
509                 .addOption(newOption(ARGUMENT.ARTIFACTORY_ENABLED, "Whether the Artifactory Analyzer should be enabled."))
510                 .addOption(newOption(ARGUMENT.PURGE_NVD, "Purges the local NVD data cache"))
511                 .addOption(newOption(ARGUMENT.DISABLE_HOSTED_SUPPRESSIONS, "Disable the usage of the hosted suppressions file"))
512                 .addOption(newOption(ARGUMENT.HOSTED_SUPPRESSIONS_FORCEUPDATE, "Force the hosted suppressions file to update even"
513                         + " if autoupdate is disabled"))
514                 .addOption(newOptionWithArg(ARGUMENT.HOSTED_SUPPRESSIONS_VALID_FOR_HOURS, "hours",
515                         "The number of hours to wait before checking for new updates of the the hosted suppressions file."))
516                 .addOption(newOptionWithArg(ARGUMENT.HOSTED_SUPPRESSIONS_URL, "url",
517                         "The URL for a mirrored hosted suppressions file"));
518 
519     }
520 
521     /**
522      * Adds the deprecated command line options to the given options collection.
523      * These are split out for purposes of not including them in the help
524      * message. We need to add the deprecated options so as not to break
525      * existing scripts.
526      *
527      * @param options a collection of command line arguments
528      */
529     @SuppressWarnings({"static-access", "deprecation"})
530     private void addDeprecatedOptions(final Options options) {
531         //not a real option - but enables java debugging via the shell script
532         options.addOption(newOption("debug",
533                 "Used to enable java debugging of the cli via dependency-check.sh."));
534     }
535 
536     /**
537      * Determines if the 'version' command line argument was passed in.
538      *
539      * @return whether or not the 'version' command line argument was passed in
540      */
541     public boolean isGetVersion() {
542         return (line != null) && line.hasOption(ARGUMENT.VERSION);
543     }
544 
545     /**
546      * Determines if the 'help' command line argument was passed in.
547      *
548      * @return whether or not the 'help' command line argument was passed in
549      */
550     public boolean isGetHelp() {
551         return (line != null) && line.hasOption(ARGUMENT.HELP);
552     }
553 
554     /**
555      * Determines if the 'scan' command line argument was passed in.
556      *
557      * @return whether or not the 'scan' command line argument was passed in
558      */
559     public boolean isRunScan() {
560         return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN);
561     }
562 
563     /**
564      * Returns the symbolic link depth (how deeply symbolic links will be
565      * followed).
566      *
567      * @return the symbolic link depth
568      */
569     public int getSymLinkDepth() {
570         int value = 0;
571         try {
572             value = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH, "0"));
573             if (value < 0) {
574                 value = 0;
575             }
576         } catch (NumberFormatException ex) {
577             LOGGER.debug("Symbolic link was not a number");
578         }
579         return value;
580     }
581 
582     /**
583      * Utility method to determine if one of the disable options has been set.
584      * If not set, this method will check the currently configured settings for
585      * the current value to return.
586      * <p>
587      * Example given `--disableArchive` on the command line would cause this
588      * method to return true for the disable archive setting.
589      *
590      * @param disableFlag the command line disable option
591      * @param setting the corresponding settings key
592      * @return true if the disable option was set, if not set the currently
593      * configured value will be returned
594      */
595     public boolean isDisabled(String disableFlag, String setting) {
596         if (line == null || !line.hasOption(disableFlag)) {
597             try {
598                 return !settings.getBoolean(setting);
599             } catch (InvalidSettingException ise) {
600                 LOGGER.warn("Invalid property setting '{}' defaulting to false", setting);
601                 return false;
602             }
603         } else {
604             return true;
605         }
606     }
607 
608     /**
609      * Returns true if the disableNodeAudit command line argument was specified.
610      *
611      * @return true if the disableNodeAudit command line argument was specified;
612      * otherwise false
613      */
614     public boolean isNodeAuditDisabled() {
615         return isDisabled(ARGUMENT.DISABLE_NODE_AUDIT, Settings.KEYS.ANALYZER_NODE_AUDIT_ENABLED);
616     }
617 
618     /**
619      * Returns true if the disableYarnAudit command line argument was specified.
620      *
621      * @return true if the disableYarnAudit command line argument was specified;
622      * otherwise false
623      */
624     public boolean isYarnAuditDisabled() {
625         return isDisabled(ARGUMENT.DISABLE_YARN_AUDIT, Settings.KEYS.ANALYZER_YARN_AUDIT_ENABLED);
626     }
627 
628     /**
629      * Returns true if the disablePnpmAudit command line argument was specified.
630      *
631      * @return true if the disablePnpmAudit command line argument was specified;
632      * otherwise false
633      */
634     public boolean isPnpmAuditDisabled() {
635         return isDisabled(ARGUMENT.DISABLE_PNPM_AUDIT, Settings.KEYS.ANALYZER_PNPM_AUDIT_ENABLED);
636     }
637 
638     /**
639      * Returns true if the Nexus Analyzer should use the configured proxy to
640      * connect to Nexus; otherwise false is returned.
641      *
642      * @return true if the Nexus Analyzer should use the configured proxy to
643      * connect to Nexus; otherwise false
644      */
645     public boolean isNexusUsesProxy() {
646         // If they didn't specify whether Nexus needs to use the proxy, we should
647         // still honor the property if it's set.
648         if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) {
649             try {
650                 return settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY);
651             } catch (InvalidSettingException ise) {
652                 return true;
653             }
654         } else {
655             return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY));
656         }
657     }
658 
659     /**
660      * Returns the argument boolean value.
661      *
662      * @param argument the argument
663      * @return the argument boolean value
664      */
665     @SuppressFBWarnings(justification = "Accepting that this is a bad practice - used a Boolean as we needed three states",
666             value = {"NP_BOOLEAN_RETURN_NULL"})
667     public Boolean getBooleanArgument(String argument) {
668         if (line != null && line.hasOption(argument)) {
669             final String value = line.getOptionValue(argument);
670             if (value != null) {
671                 return Boolean.parseBoolean(value);
672             }
673         }
674         return null;
675     }
676 
677     /**
678      * Returns the argument value for the given option.
679      *
680      * @param option the option
681      * @return the value of the argument
682      */
683     public String getStringArgument(String option) {
684         return getStringArgument(option, null);
685     }
686 
687     /**
688      * Returns the argument value for the given option.
689      *
690      * @param option the option
691      * @param key the dependency-check settings key for the option.
692      * @return the value of the argument
693      */
694     public String getStringArgument(String option, String key) {
695         if (line != null && line.hasOption(option)) {
696             if (key != null && (option.toLowerCase().endsWith("password")
697                     || option.toLowerCase().endsWith("pass"))) {
698                 LOGGER.warn("{} used on the command line, consider moving the password "
699                         + "to a properties file using the key `{}` and using the "
700                         + "--propertyfile argument instead", option, key);
701             }
702             return line.getOptionValue(option);
703         }
704         return null;
705     }
706 
707     /**
708      * Returns the argument value for the given option.
709      *
710      * @param option the option
711      * @return the value of the argument
712      */
713     public String[] getStringArguments(String option) {
714         if (line != null && line.hasOption(option)) {
715             return line.getOptionValues(option);
716         }
717         return null;
718     }
719 
720     /**
721      * Returns the argument value for the given option.
722      *
723      * @param option the option
724      * @return the value of the argument
725      */
726     public File getFileArgument(String option) {
727         final String path = line.getOptionValue(option);
728         if (path != null) {
729             return new File(path);
730         }
731         return null;
732     }
733 
734     /**
735      * Displays the command line help message to the standard output.
736      */
737     public void printHelp() {
738         final HelpFormatter formatter = new HelpFormatter();
739         final Options options = new Options();
740         addStandardOptions(options);
741         if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) {
742             addAdvancedOptions(options);
743         }
744         final String helpMsg = String.format("%n%s"
745                 + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. "
746                 + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n",
747                 settings.getString(Settings.KEYS.APPLICATION_NAME, "DependencyCheck"),
748                 settings.getString(Settings.KEYS.APPLICATION_NAME, "DependencyCheck"));
749 
750         formatter.printHelp(settings.getString(Settings.KEYS.APPLICATION_NAME, "DependencyCheck"),
751                 helpMsg,
752                 options,
753                 "",
754                 true);
755     }
756 
757     /**
758      * Retrieves the file command line parameter(s) specified for the 'scan'
759      * argument.
760      *
761      * @return the file paths specified on the command line for scan
762      */
763     public String[] getScanFiles() {
764         return line.getOptionValues(ARGUMENT.SCAN);
765     }
766 
767     /**
768      * Retrieves the list of excluded file patterns specified by the 'exclude'
769      * argument.
770      *
771      * @return the excluded file patterns
772      */
773     public String[] getExcludeList() {
774         return line.getOptionValues(ARGUMENT.EXCLUDE);
775     }
776 
777     /**
778      * Retrieves the list of retire JS content filters used to exclude JS files
779      * by content.
780      *
781      * @return the retireJS filters
782      */
783     public String[] getRetireJsFilters() {
784         return line.getOptionValues(ARGUMENT.RETIREJS_FILTERS);
785     }
786 
787     /**
788      * Returns whether or not the retireJS analyzer should exclude
789      * non-vulnerable JS from the report.
790      *
791      * @return <code>true</code> if non-vulnerable JS should be filtered in the
792      * RetireJS Analyzer; otherwise <code>null</code>
793      */
794     @SuppressFBWarnings(justification = "Accepting that this is a bad practice - but made more sense in this use case",
795             value = {"NP_BOOLEAN_RETURN_NULL"})
796     public Boolean isRetireJsFilterNonVulnerable() {
797         return (line != null && line.hasOption(ARGUMENT.RETIREJS_FILTER_NON_VULNERABLE)) ? true : null;
798     }
799 
800     /**
801      * Returns the directory to write the reports to specified on the command
802      * line.
803      *
804      * @return the path to the reports directory.
805      */
806     public String getReportDirectory() {
807         return line.getOptionValue(ARGUMENT.OUT, ".");
808     }
809 
810     /**
811      * Returns the output format specified on the command line. Defaults to HTML
812      * if no format was specified.
813      *
814      * @return the output format name.
815      */
816     public String[] getReportFormat() {
817         if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
818             return line.getOptionValues(ARGUMENT.OUTPUT_FORMAT);
819         }
820         return new String[]{"HTML"};
821     }
822 
823     /**
824      * Returns the application name specified on the command line.
825      *
826      * @return the application name.
827      */
828     public String getProjectName() {
829         String name = line.getOptionValue(ARGUMENT.PROJECT);
830         if (name == null) {
831             name = "";
832         }
833         return name;
834     }
835 
836     /**
837      * <p>
838      * Prints the manifest information to standard output.</p>
839      * <ul><li>Implementation-Title: ${pom.name}</li>
840      * <li>Implementation-Version: ${pom.version}</li></ul>
841      */
842     public void printVersionInfo() {
843         final String version = String.format("%s version %s",
844                 settings.getString(Settings.KEYS.APPLICATION_NAME, "dependency-check"),
845                 settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown"));
846         System.out.println(version);
847     }
848 
849     /**
850      * Checks if the update only flag has been set.
851      *
852      * @return <code>true</code> if the update only flag has been set; otherwise
853      * <code>false</code>.
854      */
855     public boolean isUpdateOnly() {
856         return line != null && line.hasOption(ARGUMENT.UPDATE_ONLY);
857     }
858 
859     /**
860      * Checks if the purge NVD flag has been set.
861      *
862      * @return <code>true</code> if the purge nvd flag has been set; otherwise
863      * <code>false</code>.
864      */
865     public boolean isPurge() {
866         return line != null && line.hasOption(ARGUMENT.PURGE_NVD);
867     }
868 
869     /**
870      * Returns the database driver name if specified; otherwise null is
871      * returned.
872      *
873      * @return the database driver name if specified; otherwise null is returned
874      */
875     public String getDatabaseDriverName() {
876         return line.getOptionValue(ARGUMENT.DB_DRIVER);
877     }
878 
879     /**
880      * Returns the argument value.
881      *
882      * @param argument the argument
883      * @return the value of the argument
884      */
885     public Integer getIntegerValue(String argument) {
886         final String v = line.getOptionValue(argument);
887         if (v != null) {
888             return Integer.parseInt(v);
889         }
890         return null;
891     }
892 
893     /**
894      * Checks if the option is present. If present it will return
895      * <code>true</code>; otherwise <code>false</code>.
896      *
897      * @param option the option to check
898      * @return <code>true</code> if auto-update is allowed; otherwise
899      * <code>null</code>
900      */
901     @SuppressFBWarnings(justification = "Accepting that this is a bad practice - but made more sense in this use case",
902             value = {"NP_BOOLEAN_RETURN_NULL"})
903     public Boolean hasOption(String option) {
904         return (line != null && line.hasOption(option)) ? true : null;
905     }
906 
907     /**
908      * Returns the CVSS value to fail on.
909      *
910      * @return 11 if nothing is set. Otherwise it returns the int passed from
911      * the command line arg
912      */
913     public float getFailOnCVSS() {
914         if (line.hasOption(ARGUMENT.FAIL_ON_CVSS)) {
915             final String value = line.getOptionValue(ARGUMENT.FAIL_ON_CVSS);
916             try {
917                 return Float.parseFloat(value);
918             } catch (NumberFormatException nfe) {
919                 return 11;
920             }
921         } else {
922             return 11;
923         }
924     }
925 
926     /**
927      * Returns the float argument for the given option.
928      *
929      * @param option the option
930      * @param defaultValue the value if the option is not present
931      * @return the value of the argument if present; otherwise the defaultValue
932      */
933     public float getFloatArgument(String option, float defaultValue) {
934         if (line.hasOption(option)) {
935             final String value = line.getOptionValue(option);
936             try {
937                 return Integer.parseInt(value);
938             } catch (NumberFormatException nfe) {
939                 return defaultValue;
940             }
941         } else {
942             return defaultValue;
943         }
944     }
945 
946     /**
947      * Builds a new option.
948      *
949      * @param name the long name
950      * @param description the description
951      * @return a new option
952      */
953     private Option newOption(String name, String description) {
954         return Option.builder().longOpt(name).desc(description).build();
955     }
956 
957     /**
958      * Builds a new option.
959      *
960      * @param shortName the short name
961      * @param name the long name
962      * @param description the description
963      * @return a new option
964      */
965     private Option newOption(String shortName, String name, String description) {
966         return Option.builder(shortName).longOpt(name).desc(description).build();
967     }
968 
969     /**
970      * Builds a new option.
971      *
972      * @param name the long name
973      * @param arg the argument name
974      * @param description the description
975      * @return a new option
976      */
977     private Option newOptionWithArg(String name, String arg, String description) {
978         return Option.builder().longOpt(name).argName(arg).hasArg().desc(description).build();
979     }
980 
981     /**
982      * Builds a new option.
983      *
984      * @param shortName the short name
985      * @param name the long name
986      * @param arg the argument name
987      * @param description the description
988      * @return a new option
989      */
990     private Option newOptionWithArg(String shortName, String name, String arg, String description) {
991         return Option.builder(shortName).longOpt(name).argName(arg).hasArg().desc(description).build();
992     }
993 
994     /**
995      * Builds a new option group so that an option can be specified multiple
996      * times on the command line.
997      *
998      * @param option the option to add to the group
999      * @return a new option group
1000      */
1001     private OptionGroup newOptionGroup(Option option) {
1002         final OptionGroup group = new OptionGroup();
1003         group.addOption(option);
1004         return group;
1005     }
1006 
1007     /**
1008      * A collection of static final strings that represent the possible command
1009      * line arguments.
1010      */
1011     public static class ARGUMENT {
1012 
1013         /**
1014          * The long CLI argument name specifying the directory/file to scan.
1015          */
1016         public static final String SCAN = "scan";
1017         /**
1018          * The short CLI argument name specifying the directory/file to scan.
1019          */
1020         public static final String SCAN_SHORT = "s";
1021         /**
1022          * The long CLI argument name specifying that the CPE/CVE/etc. data
1023          * should not be automatically updated.
1024          */
1025         public static final String DISABLE_AUTO_UPDATE = "noupdate";
1026         /**
1027          * The short CLI argument name specifying that the CPE/CVE/etc. data
1028          * should not be automatically updated.
1029          */
1030         public static final String DISABLE_AUTO_UPDATE_SHORT = "n";
1031         /**
1032          * The long CLI argument name specifying that only the update phase
1033          * should be executed; no scan should be run.
1034          */
1035         public static final String UPDATE_ONLY = "updateonly";
1036         /**
1037          * The long CLI argument name specifying that only the update phase
1038          * should be executed; no scan should be run.
1039          */
1040         public static final String PURGE_NVD = "purge";
1041         /**
1042          * The long CLI argument name specifying the directory to write the
1043          * reports to.
1044          */
1045         public static final String OUT = "out";
1046         /**
1047          * The short CLI argument name specifying the directory to write the
1048          * reports to.
1049          */
1050         public static final String OUT_SHORT = "o";
1051         /**
1052          * The long CLI argument name specifying the output format to write the
1053          * reports to.
1054          */
1055         public static final String OUTPUT_FORMAT = "format";
1056         /**
1057          * The short CLI argument name specifying the output format to write the
1058          * reports to.
1059          */
1060         public static final String OUTPUT_FORMAT_SHORT = "f";
1061         /**
1062          * The long CLI argument name specifying the name of the project to be
1063          * scanned.
1064          */
1065         public static final String PROJECT = "project";
1066         /**
1067          * The long CLI argument name asking for help.
1068          */
1069         public static final String HELP = "help";
1070         /**
1071          * The long CLI argument name asking for advanced help.
1072          */
1073         public static final String ADVANCED_HELP = "advancedHelp";
1074         /**
1075          * The short CLI argument name asking for help.
1076          */
1077         public static final String HELP_SHORT = "h";
1078         /**
1079          * The long CLI argument name asking for the version.
1080          */
1081         public static final String VERSION_SHORT = "v";
1082         /**
1083          * The short CLI argument name asking for the version.
1084          */
1085         public static final String VERSION = "version";
1086         /**
1087          * The CLI argument name indicating the proxy port.
1088          */
1089         public static final String PROXY_PORT = "proxyport";
1090         /**
1091          * The CLI argument name indicating the proxy server.
1092          */
1093         public static final String PROXY_SERVER = "proxyserver";
1094         /**
1095          * The CLI argument name indicating the proxy username.
1096          */
1097         public static final String PROXY_USERNAME = "proxyuser";
1098         /**
1099          * The CLI argument name indicating the proxy password.
1100          */
1101         public static final String PROXY_PASSWORD = "proxypass";
1102         /**
1103          * The CLI argument name indicating the proxy proxy exclusion list.
1104          */
1105         public static final String NON_PROXY_HOSTS = "nonProxyHosts";
1106         /**
1107          * The short CLI argument name indicating the connection timeout.
1108          */
1109         public static final String CONNECTION_TIMEOUT_SHORT = "c";
1110         /**
1111          * The CLI argument name indicating the connection timeout.
1112          */
1113         public static final String CONNECTION_TIMEOUT = "connectiontimeout";
1114         /**
1115          * The CLI argument name indicating the connection read timeout.
1116          */
1117         public static final String CONNECTION_READ_TIMEOUT = "readtimeout";
1118         /**
1119          * The short CLI argument name for setting the location of an additional
1120          * properties file.
1121          */
1122         public static final String PROP_SHORT = "P";
1123         /**
1124          * The CLI argument name for setting the location of an additional
1125          * properties file.
1126          */
1127         public static final String PROP = "propertyfile";
1128         /**
1129          * The CLI argument name for setting the location of the data directory.
1130          */
1131         public static final String DATA_DIRECTORY = "data";
1132         /**
1133          * The CLI argument name for setting the URL for the NVD API Endpoint
1134          */
1135         public static final String NVD_API_ENDPOINT = "nvdApiEndpoint";
1136         /**
1137          * The CLI argument name for setting the URL for the NVD API Key.
1138          */
1139         public static final String NVD_API_KEY = "nvdApiKey";
1140         /**
1141         * The CLI argument name for setting the maximum number of retry requests for a single call to the NVD API.
1142         */
1143         public static final String NVD_API_MAX_RETRY_COUNT = "nvdMaxRetryCount";
1144         /**
1145          * The CLI argument name for setting the number of hours to wait before
1146          * checking for new updates from the NVD.
1147          */
1148         public static final String NVD_API_VALID_FOR_HOURS = "nvdValidForHours";
1149         /**
1150          * The CLI argument name for the NVD API Data Feed URL.
1151          */
1152         public static final String NVD_API_DATAFEED_URL = "nvdDatafeed";
1153         /**
1154          * The username for basic auth to the CVE data.
1155          */
1156         public static final String NVD_API_DATAFEED_USER = "nvdUser";
1157         /**
1158          * The password for basic auth to the CVE data.
1159          */
1160         public static final String NVD_API_DATAFEED_PASSWORD = "nvdPassword";
1161         /**
1162          * The time in milliseconds to wait between downloading NVD API data.
1163          */
1164         public static final String NVD_API_DELAY = "nvdApiDelay";
1165         /**
1166          * The short CLI argument name for setting the location of the data
1167          * directory.
1168          */
1169         public static final String DATA_DIRECTORY_SHORT = "d";
1170         /**
1171          * The CLI argument name for setting the location of the data directory.
1172          */
1173         public static final String VERBOSE_LOG = "log";
1174         /**
1175          * The short CLI argument name for setting the location of the data
1176          * directory.
1177          */
1178         public static final String VERBOSE_LOG_SHORT = "l";
1179         /**
1180          * The CLI argument name for setting the depth of symbolic links that
1181          * will be followed.
1182          */
1183         public static final String SYM_LINK_DEPTH = "symLink";
1184         /**
1185          * The CLI argument name for setting the location of the suppression
1186          * file(s).
1187          */
1188         public static final String SUPPRESSION_FILES = "suppression";
1189         /**
1190          * The CLI argument name for setting the location of the hint file.
1191          */
1192         public static final String HINTS_FILE = "hints";
1193         /**
1194          * Disables the Jar Analyzer.
1195          */
1196         public static final String DISABLE_JAR = "disableJar";
1197         /**
1198          * Disable the MS Build Analyzer.
1199          */
1200         public static final String DISABLE_MSBUILD = "disableMSBuild";
1201         /**
1202          * Disables the Archive Analyzer.
1203          */
1204         public static final String DISABLE_ARCHIVE = "disableArchive";
1205         /**
1206          * Disables the Known Exploited Analyzer.
1207          */
1208         public static final String DISABLE_KEV = "disableKnownExploited";
1209         /**
1210          * The URL to the CISA Known Exploited Vulnerability JSON datafeed.
1211          */
1212         public static final String KEV_URL = "kevURL";
1213         /**
1214          * Disables the Python Distribution Analyzer.
1215          */
1216         public static final String DISABLE_PY_DIST = "disablePyDist";
1217         /**
1218          * Disables the Python Package Analyzer.
1219          */
1220         public static final String DISABLE_PY_PKG = "disablePyPkg";
1221         /**
1222          * Disables the Elixir mix audit Analyzer.
1223          */
1224         public static final String DISABLE_MIX_AUDIT = "disableMixAudit";
1225         /**
1226          * Disables the Golang Dependency Analyzer.
1227          */
1228         public static final String DISABLE_GO_DEP = "disableGolangDep";
1229         /**
1230          * Disables the PHP Composer Analyzer.
1231          */
1232         public static final String DISABLE_COMPOSER = "disableComposer";
1233         /**
1234          * Disables the Perl CPAN File Analyzer.
1235          */
1236         public static final String DISABLE_CPAN = "disableCpan";
1237         /**
1238          * Disables the Golang Mod Analyzer.
1239          */
1240         public static final String DISABLE_GOLANG_MOD = "disableGolangMod";
1241         /**
1242          * Disables the Dart Analyzer.
1243          */
1244         public static final String DISABLE_DART = "disableDart";
1245         /**
1246          * The CLI argument name for setting the path to `go`.
1247          */
1248         public static final String PATH_TO_GO = "go";
1249         /**
1250          * The CLI argument name for setting the path to `yarn`.
1251          */
1252         public static final String PATH_TO_YARN = "yarn";
1253         /**
1254          * The CLI argument name for setting the path to `pnpm`.
1255          */
1256         public static final String PATH_TO_PNPM = "pnpm";
1257         /**
1258          * Disables the Ruby Gemspec Analyzer.
1259          */
1260         public static final String DISABLE_RUBYGEMS = "disableRubygems";
1261         /**
1262          * Disables the Autoconf Analyzer.
1263          */
1264         public static final String DISABLE_AUTOCONF = "disableAutoconf";
1265         /**
1266          * Disables the Maven install Analyzer.
1267          */
1268         public static final String DISABLE_MAVEN_INSTALL = "disableMavenInstall";
1269         /**
1270          * Disables the pip Analyzer.
1271          */
1272         public static final String DISABLE_PIP = "disablePip";
1273         /**
1274          * Disables the Pipfile Analyzer.
1275          */
1276         public static final String DISABLE_PIPFILE = "disablePipfile";
1277         /**
1278          * Disables the Poetry Analyzer.
1279          */
1280         public static final String DISABLE_POETRY = "disablePoetry";
1281         /**
1282          * Disables the Cmake Analyzer.
1283          */
1284         public static final String DISABLE_CMAKE = "disableCmake";
1285         /**
1286          * Disables the cocoapods analyzer.
1287          */
1288         public static final String DISABLE_COCOAPODS = "disableCocoapodsAnalyzer";
1289         /**
1290          * Disables the swift package manager analyzer.
1291          */
1292         public static final String DISABLE_SWIFT = "disableSwiftPackageManagerAnalyzer";
1293         /**
1294          * Disables the swift package resolved analyzer.
1295          */
1296         public static final String DISABLE_SWIFT_RESOLVED = "disableSwiftPackageResolvedAnalyzer";
1297         /**
1298          * Disables the Assembly Analyzer.
1299          */
1300         public static final String DISABLE_ASSEMBLY = "disableAssembly";
1301         /**
1302          * Disables the Ruby Bundler Audit Analyzer.
1303          */
1304         public static final String DISABLE_BUNDLE_AUDIT = "disableBundleAudit";
1305         /**
1306          * Disables the File Name Analyzer.
1307          */
1308         public static final String DISABLE_FILENAME = "disableFileName";
1309         /**
1310          * Disables the Nuspec Analyzer.
1311          */
1312         public static final String DISABLE_NUSPEC = "disableNuspec";
1313         /**
1314          * Disables the Nuget packages.config Analyzer.
1315          */
1316         public static final String DISABLE_NUGETCONF = "disableNugetconf";
1317         /**
1318          * Disables the Central Analyzer.
1319          */
1320         public static final String DISABLE_CENTRAL = "disableCentral";
1321         /**
1322          * Disables the Central Analyzer's ability to cache results locally.
1323          */
1324         public static final String DISABLE_CENTRAL_CACHE = "disableCentralCache";
1325         /**
1326          * The alternative URL for Maven Central Search.
1327          */
1328         public static final String CENTRAL_URL = "centralUrl";
1329         /**
1330          * Disables the Nexus Analyzer.
1331          */
1332         public static final String ENABLE_NEXUS = "enableNexus";
1333         /**
1334          * Disables the Sonatype OSS Index Analyzer.
1335          */
1336         public static final String DISABLE_OSSINDEX = "disableOssIndex";
1337         /**
1338          * Disables the Sonatype OSS Index Analyzer's ability to cache results
1339          * locally.
1340          */
1341         public static final String DISABLE_OSSINDEX_CACHE = "disableOssIndexCache";
1342         /**
1343          * The alternative URL for the Sonatype OSS Index.
1344          */
1345         public static final String OSSINDEX_URL = "ossIndexUrl";
1346         /**
1347          * The username for the Sonatype OSS Index.
1348          */
1349         public static final String OSSINDEX_USERNAME = "ossIndexUsername";
1350         /**
1351          * The password for the Sonatype OSS Index.
1352          */
1353         public static final String OSSINDEX_PASSWORD = "ossIndexPassword";
1354         /**
1355          * The password for the Sonatype OSS Index.
1356          */
1357         public static final String OSSINDEX_WARN_ONLY_ON_REMOTE_ERRORS = "ossIndexRemoteErrorWarnOnly";
1358         /**
1359          * Disables the OpenSSL Analyzer.
1360          */
1361         public static final String DISABLE_OPENSSL = "disableOpenSSL";
1362         /**
1363          * Disables the Node.js Package Analyzer.
1364          */
1365         public static final String DISABLE_NODE_JS = "disableNodeJS";
1366         /**
1367          * Skips dev dependencies in Node Package Analyzer.
1368          */
1369         public static final String NODE_PACKAGE_SKIP_DEV_DEPENDENCIES = "nodePackageSkipDevDependencies";
1370         /**
1371          * Disables the Node Audit Analyzer.
1372          */
1373         public static final String DISABLE_NODE_AUDIT = "disableNodeAudit";
1374         /**
1375          * Disables the Yarn Audit Analyzer.
1376          */
1377         public static final String DISABLE_YARN_AUDIT = "disableYarnAudit";
1378         /**
1379          * Disables the Pnpm Audit Analyzer.
1380          */
1381         public static final String DISABLE_PNPM_AUDIT = "disablePnpmAudit";
1382         /**
1383          * Disables the Node Audit Analyzer's ability to cache results locally.
1384          */
1385         public static final String DISABLE_NODE_AUDIT_CACHE = "disableNodeAuditCache";
1386         /**
1387          * Configures the Node Audit Analyzer to skip the dev dependencies.
1388          */
1389         public static final String DISABLE_NODE_AUDIT_SKIPDEV = "nodeAuditSkipDevDependencies";
1390         /**
1391          * Disables the RetireJS Analyzer.
1392          */
1393         public static final String DISABLE_RETIRE_JS = "disableRetireJS";
1394         /**
1395          * Whether the RetireJS Analyzer will update regardless of the
1396          * `autoupdate` setting.
1397          */
1398         public static final String RETIRE_JS_FORCEUPDATE = "retireJsForceUpdate";
1399         /**
1400          * The URL to the retire JS repository.
1401          */
1402         public static final String RETIREJS_URL = "retireJsUrl";
1403         /**
1404          * The username to the retire JS repository.
1405          */
1406         public static final String RETIREJS_URL_USER = "retireJsUrlUser";
1407         /**
1408          * The password to the retire JS repository.
1409          */
1410         public static final String RETIREJS_URL_PASSWORD = "retireJsUrlPass";
1411         /**
1412          * The URL of the nexus server.
1413          */
1414         public static final String NEXUS_URL = "nexus";
1415         /**
1416          * The username for the nexus server.
1417          */
1418         public static final String NEXUS_USERNAME = "nexusUser";
1419         /**
1420          * The password for the nexus server.
1421          */
1422         public static final String NEXUS_PASSWORD = "nexusPass";
1423         /**
1424          * Whether or not the defined proxy should be used when connecting to
1425          * Nexus.
1426          */
1427         public static final String NEXUS_USES_PROXY = "nexusUsesProxy";
1428         /**
1429          * The CLI argument name for setting the connection string.
1430          */
1431         public static final String CONNECTION_STRING = "connectionString";
1432         /**
1433          * The CLI argument name for setting the database user name.
1434          */
1435         public static final String DB_NAME = "dbUser";
1436         /**
1437          * The CLI argument name for setting the database password.
1438          */
1439         public static final String DB_PASSWORD = "dbPassword";
1440         /**
1441          * The CLI argument name for setting the database driver name.
1442          */
1443         public static final String DB_DRIVER = "dbDriverName";
1444         /**
1445          * The CLI argument name for setting the path to the database driver; in
1446          * case it is not on the class path.
1447          */
1448         public static final String DB_DRIVER_PATH = "dbDriverPath";
1449         /**
1450          * The CLI argument name for setting the path to dotnet core.
1451          */
1452         public static final String PATH_TO_CORE = "dotnet";
1453         /**
1454          * The CLI argument name for setting extra extensions.
1455          */
1456         public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions";
1457         /**
1458          * Exclude path argument.
1459          */
1460         public static final String EXCLUDE = "exclude";
1461         /**
1462          * The CLI argument name for setting the path to bundle-audit for Ruby
1463          * bundle analysis.
1464          */
1465         public static final String PATH_TO_BUNDLE_AUDIT = "bundleAudit";
1466         /**
1467          * The CLI argument name for setting the path that should be used as the
1468          * working directory that the bundle-audit command used for Ruby bundle
1469          * analysis should be executed from. This will allow for the usage of
1470          * rbenv
1471          */
1472         public static final String PATH_TO_BUNDLE_AUDIT_WORKING_DIRECTORY = "bundleAuditWorkingDirectory";
1473         /**
1474          * The CLI argument name for setting the path to mix_audit for Elixir
1475          * analysis.
1476          */
1477         public static final String PATH_TO_MIX_AUDIT = "mixAudit";
1478         /**
1479          * The CLI argument to enable the experimental analyzers.
1480          */
1481         public static final String EXPERIMENTAL = "enableExperimental";
1482         /**
1483          * The CLI argument to enable the retired analyzers.
1484          */
1485         public static final String RETIRED = "enableRetired";
1486         /**
1487          * The CLI argument for the retire js content filters.
1488          */
1489         public static final String RETIREJS_FILTERS = "retirejsFilter";
1490         /**
1491          * The CLI argument for the retire js content filters.
1492          */
1493         public static final String RETIREJS_FILTER_NON_VULNERABLE = "retirejsFilterNonVulnerable";
1494         /**
1495          * The CLI argument for indicating if the Artifactory analyzer should be
1496          * enabled.
1497          */
1498         public static final String ARTIFACTORY_ENABLED = "enableArtifactory";
1499         /**
1500          * The CLI argument for indicating if the Artifactory analyzer should
1501          * use the proxy.
1502          */
1503         public static final String ARTIFACTORY_URL = "artifactoryUrl";
1504         /**
1505          * The CLI argument for indicating the Artifactory username.
1506          */
1507         public static final String ARTIFACTORY_USERNAME = "artifactoryUsername";
1508         /**
1509          * The CLI argument for indicating the Artifactory API token.
1510          */
1511         public static final String ARTIFACTORY_API_TOKEN = "artifactoryApiToken";
1512         /**
1513          * The CLI argument for indicating the Artifactory bearer token.
1514          */
1515         public static final String ARTIFACTORY_BEARER_TOKEN = "artifactoryBearerToken";
1516         /**
1517          * The CLI argument for indicating if the Artifactory analyzer should
1518          * use the proxy.
1519          */
1520         public static final String ARTIFACTORY_USES_PROXY = "artifactoryUseProxy";
1521         /**
1522          * The CLI argument for indicating if the Artifactory analyzer should
1523          * use the parallel analysis.
1524          */
1525         public static final String ARTIFACTORY_PARALLEL_ANALYSIS = "artifactoryParallelAnalysis";
1526         /**
1527          * The CLI argument to configure when the execution should be considered
1528          * a failure.
1529          */
1530         public static final String FAIL_ON_CVSS = "failOnCVSS";
1531         /**
1532          * The CLI argument to configure if the XML and JSON reports should be
1533          * pretty printed.
1534          */
1535         public static final String PRETTY_PRINT = "prettyPrint";
1536         /**
1537          * The CLI argument to set the threshold that is considered a failure
1538          * when generating the JUNIT report format.
1539          */
1540         public static final String FAIL_JUNIT_ON_CVSS = "junitFailOnCVSS";
1541         /**
1542          * The CLI argument to set the number of hours to wait before
1543          * re-checking hosted suppressions file for updates.
1544          */
1545         public static final String DISABLE_HOSTED_SUPPRESSIONS = "disableHostedSuppressions";
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 HOSTED_SUPPRESSIONS_VALID_FOR_HOURS = "hostedSuppressionsValidForHours";
1551         /**
1552          * The CLI argument to set Whether the hosted suppressions file will
1553          * update regardless of the `noupdate` argument.
1554          */
1555         public static final String HOSTED_SUPPRESSIONS_FORCEUPDATE = "hostedSuppressionsForceUpdate";
1556         /**
1557          * The CLI argument to set the location of a mirrored hosted
1558          * suppressions file .
1559          */
1560         public static final String HOSTED_SUPPRESSIONS_URL = "hostedSuppressionsUrl";
1561     }
1562 }