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 java.io.File;
21  import java.io.FileNotFoundException;
22  
23  import org.apache.commons.cli.CommandLine;
24  import org.apache.commons.cli.CommandLineParser;
25  import org.apache.commons.cli.DefaultParser;
26  import org.apache.commons.cli.HelpFormatter;
27  import org.apache.commons.cli.Option;
28  import org.apache.commons.cli.OptionGroup;
29  import org.apache.commons.cli.Options;
30  import org.apache.commons.cli.ParseException;
31  import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
32  import org.owasp.dependencycheck.utils.InvalidSettingException;
33  import org.owasp.dependencycheck.utils.Settings;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  /**
38   * A utility to parse command line arguments for the DependencyCheck.
39   *
40   * @author Jeremy Long
41   */
42  public final class CliParser {
43  
44      /**
45       * The logger.
46       */
47      private static final Logger LOGGER = LoggerFactory.getLogger(CliParser.class);
48      /**
49       * The command line.
50       */
51      private CommandLine line;
52      /**
53       * Indicates whether the arguments are valid.
54       */
55      private boolean isValid = true;
56  
57      /**
58       * Parses the arguments passed in and captures the results for later use.
59       *
60       * @param args the command line arguments
61       * @throws FileNotFoundException is thrown when a 'file' argument does not
62       * point to a file that exists.
63       * @throws ParseException is thrown when a Parse Exception occurs.
64       */
65      public void parse(String[] args) throws FileNotFoundException, ParseException {
66          line = parseArgs(args);
67  
68          if (line != null) {
69              validateArgs();
70          }
71      }
72  
73      /**
74       * Parses the command line arguments.
75       *
76       * @param args the command line arguments
77       * @return the results of parsing the command line arguments
78       * @throws ParseException if the arguments are invalid
79       */
80      private CommandLine parseArgs(String[] args) throws ParseException {
81          final CommandLineParser parser = new DefaultParser();
82          final Options options = createCommandLineOptions();
83          return parser.parse(options, args);
84      }
85  
86      /**
87       * Validates that the command line arguments are valid.
88       *
89       * @throws FileNotFoundException if there is a file specified by either the
90       * SCAN or CPE command line arguments that does not exist.
91       * @throws ParseException is thrown if there is an exception parsing the
92       * command line.
93       */
94      private void validateArgs() throws FileNotFoundException, ParseException {
95          if (isUpdateOnly() || isRunScan()) {
96              final String value = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS);
97              if (value != null) {
98                  try {
99                      final int i = Integer.parseInt(value);
100                     if (i < 0) {
101                         throw new ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0.");
102                     }
103                 } catch (NumberFormatException ex) {
104                     throw new ParseException("Invalid Setting: cveValidForHours must be a number greater than or equal to 0.");
105                 }
106             }
107         }
108         if (isRunScan()) {
109             validatePathExists(getScanFiles(), ARGUMENT.SCAN);
110             validatePathExists(getReportDirectory(), ARGUMENT.OUT);
111             if (getPathToMono() != null) {
112                 validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO);
113             }
114             if (!line.hasOption(ARGUMENT.APP_NAME) && !line.hasOption(ARGUMENT.PROJECT)) {
115                 throw new ParseException("Missing '" + ARGUMENT.PROJECT + "' argument; the scan cannot be run without the an project name.");
116             }
117             if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
118                 final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT);
119                 try {
120                     Format.valueOf(format);
121                 } catch (IllegalArgumentException ex) {
122                     final String msg = String.format("An invalid 'format' of '%s' was specified. "
123                             + "Supported output formats are XML, HTML, VULN, or ALL", format);
124                     throw new ParseException(msg);
125                 }
126             }
127             if ((getBaseCve12Url() != null || getBaseCve20Url() != null || getModifiedCve12Url() != null || getModifiedCve20Url() != null)
128                     && (getBaseCve12Url() == null || getBaseCve20Url() == null || getModifiedCve12Url() == null || getModifiedCve20Url() == null)) {
129                 final String msg = "If one of the CVE URLs is specified they must all be specified; please add the missing CVE URL.";
130                 throw new ParseException(msg);
131             }
132             if (line.hasOption((ARGUMENT.SYM_LINK_DEPTH))) {
133                 try {
134                     final int i = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH));
135                     if (i < 0) {
136                         throw new ParseException("Symbolic Link Depth (symLink) must be greater than zero.");
137                     }
138                 } catch (NumberFormatException ex) {
139                     throw new ParseException("Symbolic Link Depth (symLink) is not a number.");
140                 }
141             }
142         }
143     }
144 
145     /**
146      * Validates whether or not the path(s) points at a file that exists; if the
147      * path(s) does not point to an existing file a FileNotFoundException is
148      * thrown.
149      *
150      * @param paths the paths to validate if they exists
151      * @param optType the option being validated (e.g. scan, out, etc.)
152      * @throws FileNotFoundException is thrown if one of the paths being
153      * validated does not exist.
154      */
155     private void validatePathExists(String[] paths, String optType) throws FileNotFoundException {
156         for (String path : paths) {
157             validatePathExists(path, optType);
158         }
159     }
160 
161     /**
162      * Validates whether or not the path points at a file that exists; if the
163      * path does not point to an existing file a FileNotFoundException is
164      * thrown.
165      *
166      * @param path the paths to validate if they exists
167      * @param argumentName the argument being validated (e.g. scan, out, etc.)
168      * @throws FileNotFoundException is thrown if the path being validated does
169      * not exist.
170      */
171     private void validatePathExists(String path, String argumentName) throws FileNotFoundException {
172         if (path == null) {
173             isValid = false;
174             final String msg = String.format("Invalid '%s' argument: null", argumentName);
175             throw new FileNotFoundException(msg);
176         } else if (!path.contains("*") && !path.contains("?")) {
177             File f = new File(path);
178             if ("o".equalsIgnoreCase(argumentName.substring(0, 1)) && !"ALL".equalsIgnoreCase(this.getReportFormat())) {
179                 final String checkPath = path.toLowerCase();
180                 if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) {
181                     if (f.getParentFile() == null) {
182                         f = new File(".", path);
183                     }
184                     if (!f.getParentFile().isDirectory()) {
185                         isValid = false;
186                         final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
187                         throw new FileNotFoundException(msg);
188                     }
189                 }
190             } else if (!f.exists()) {
191                 isValid = false;
192                 final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
193                 throw new FileNotFoundException(msg);
194             }
195         } else if (path.startsWith("//") || path.startsWith("\\\\")) {
196             isValid = false;
197             final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path);
198             throw new FileNotFoundException(msg);
199         } else if ((path.endsWith("/*") && !path.endsWith("**/*")) || (path.endsWith("\\*") && path.endsWith("**\\*"))) {
200             final String msg = String.format("Possibly incorrect path '%s' from argument '%s' because it ends with a slash star; "
201                     + "dependency-check uses ant-style paths", path, argumentName);
202             LOGGER.warn(msg);
203         }
204     }
205 
206     /**
207      * Generates an Options collection that is used to parse the command line
208      * and to display the help message.
209      *
210      * @return the command line options used for parsing the command line
211      */
212     @SuppressWarnings("static-access")
213     private Options createCommandLineOptions() {
214         final Options options = new Options();
215         addStandardOptions(options);
216         addAdvancedOptions(options);
217         addDeprecatedOptions(options);
218         return options;
219     }
220 
221     /**
222      * Adds the standard command line options to the given options collection.
223      *
224      * @param options a collection of command line arguments
225      * @throws IllegalArgumentException thrown if there is an exception
226      */
227     @SuppressWarnings("static-access")
228     private void addStandardOptions(final Options options) throws IllegalArgumentException {
229         final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false,
230                 "Print this message.");
231 
232         final Option advancedHelp = Option.builder().longOpt(ARGUMENT.ADVANCED_HELP)
233                 .desc("Print the advanced help message.").build();
234 
235         final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION,
236                 false, "Print the version information.");
237 
238         final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE,
239                 false, "Disables the automatic updating of the CPE data.");
240 
241         final Option projectName = Option.builder().hasArg().argName("name").longOpt(ARGUMENT.PROJECT)
242                 .desc("The name of the project being scanned. This is a required argument.")
243                 .build();
244 
245         final Option path = Option.builder(ARGUMENT.SCAN_SHORT).argName("path").hasArg().longOpt(ARGUMENT.SCAN)
246                 .desc("The path to scan - this option can be specified multiple times. Ant style"
247                         + " paths are supported (e.g. path/**/*.jar).")
248                 .build();
249 
250         final Option excludes = Option.builder().argName("pattern").hasArg().longOpt(ARGUMENT.EXCLUDE)
251                 .desc("Specify and exclusion pattern. This option can be specified multiple times"
252                         + " and it accepts Ant style excludsions.")
253                 .build();
254 
255         final Option props = Option.builder(ARGUMENT.PROP_SHORT).argName("file").hasArg().longOpt(ARGUMENT.PROP)
256                 .desc("A property file to load.")
257                 .build();
258 
259         final Option out = Option.builder(ARGUMENT.OUT_SHORT).argName("path").hasArg().longOpt(ARGUMENT.OUT)
260                 .desc("The folder to write reports to. This defaults to the current directory. "
261                         + "It is possible to set this to a specific file name if the format argument is not set to ALL.")
262                 .build();
263 
264         final Option outputFormat = Option.builder(ARGUMENT.OUTPUT_FORMAT_SHORT).argName("format").hasArg().longOpt(ARGUMENT.OUTPUT_FORMAT)
265                 .desc("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.")
266                 .build();
267 
268         final Option verboseLog = Option.builder(ARGUMENT.VERBOSE_LOG_SHORT).argName("file").hasArg().longOpt(ARGUMENT.VERBOSE_LOG)
269                 .desc("The file path to write verbose logging information.")
270                 .build();
271 
272         final Option symLinkDepth = Option.builder().argName("depth").hasArg().longOpt(ARGUMENT.SYM_LINK_DEPTH)
273                 .desc("Sets how deep nested symbolic links will be followed; 0 indicates symbolic links will not be followed.")
274                 .build();
275 
276         final Option suppressionFile = Option.builder().argName("file").hasArg().longOpt(ARGUMENT.SUPPRESSION_FILE)
277                 .desc("The file path to the suppression XML file.")
278                 .build();
279 
280         final Option cveValidForHours = Option.builder().argName("hours").hasArg().longOpt(ARGUMENT.CVE_VALID_FOR_HOURS)
281                 .desc("The number of hours to wait before checking for new updates from the NVD.")
282                 .build();
283 
284         final Option experimentalEnabled = Option.builder().longOpt(ARGUMENT.EXPERIMENTAL)
285                 .desc("Enables the experimental analzers.")
286                 .build();
287 
288         //This is an option group because it can be specified more then once.
289         final OptionGroup og = new OptionGroup();
290         og.addOption(path);
291 
292         final OptionGroup exog = new OptionGroup();
293         exog.addOption(excludes);
294 
295         options.addOptionGroup(og)
296                 .addOptionGroup(exog)
297                 .addOption(projectName)
298                 .addOption(out)
299                 .addOption(outputFormat)
300                 .addOption(version)
301                 .addOption(help)
302                 .addOption(advancedHelp)
303                 .addOption(noUpdate)
304                 .addOption(symLinkDepth)
305                 .addOption(props)
306                 .addOption(verboseLog)
307                 .addOption(suppressionFile)
308                 .addOption(cveValidForHours)
309                 .addOption(experimentalEnabled);
310     }
311 
312     /**
313      * Adds the advanced command line options to the given options collection.
314      * These are split out for purposes of being able to display two different
315      * help messages.
316      *
317      * @param options a collection of command line arguments
318      * @throws IllegalArgumentException thrown if there is an exception
319      */
320     @SuppressWarnings("static-access")
321     private void addAdvancedOptions(final Options options) throws IllegalArgumentException {
322 
323         final Option cve12Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_12)
324                 .desc("Base URL for each year’s CVE 1.2, the %d will be replaced with the year. ")
325                 .build();
326 
327         final Option cve20Base = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_BASE_20)
328                 .desc("Base URL for each year’s CVE 2.0, the %d will be replaced with the year.")
329                 .build();
330 
331         final Option cve12Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_12)
332                 .desc("URL for the modified CVE 1.2.")
333                 .build();
334 
335         final Option cve20Modified = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.CVE_MOD_20)
336                 .desc("URL for the modified CVE 2.0.")
337                 .build();
338 
339         final Option updateOnly = Option.builder().longOpt(ARGUMENT.UPDATE_ONLY)
340                 .desc("Only update the local NVD data cache; no scan will be executed.").build();
341 
342         final Option data = Option.builder(ARGUMENT.DATA_DIRECTORY_SHORT).argName("path").hasArg().longOpt(ARGUMENT.DATA_DIRECTORY)
343                 .desc("The location of the H2 Database file. This option should generally not be set.")
344                 .build();
345 
346         final Option nexusUrl = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.NEXUS_URL)
347                 .desc("The url to the Nexus Server's REST API Endpoint (http://domain/nexus/service/local). "
348                         + "If not set the Nexus Analyzer will be disabled.").build();
349 
350         final Option nexusUsesProxy = Option.builder().argName("true/false").hasArg().longOpt(ARGUMENT.NEXUS_USES_PROXY)
351                 .desc("Whether or not the configured proxy should be used when connecting to Nexus.")
352                 .build();
353 
354         final Option additionalZipExtensions = Option.builder().argName("extensions").hasArg()
355                 .longOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS)
356                 .desc("A comma separated list of additional extensions to be scanned as ZIP files "
357                         + "(ZIP, EAR, WAR are already treated as zip files)").build();
358 
359         final Option pathToMono = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.PATH_TO_MONO)
360                 .desc("The path to Mono for .NET Assembly analysis on non-windows systems.")
361                 .build();
362 
363         final Option pathToBundleAudit = Option.builder().argName("path").hasArg()
364                 .longOpt(ARGUMENT.PATH_TO_BUNDLE_AUDIT)
365                 .desc("The path to bundle-audit for Gem bundle analysis.").build();
366 
367         final Option connectionTimeout = Option.builder(ARGUMENT.CONNECTION_TIMEOUT_SHORT).argName("timeout").hasArg()
368                 .longOpt(ARGUMENT.CONNECTION_TIMEOUT).desc("The connection timeout (in milliseconds) to use when downloading resources.")
369                 .build();
370 
371         final Option proxyServer = Option.builder().argName("server").hasArg().longOpt(ARGUMENT.PROXY_SERVER)
372                 .desc("The proxy server to use when downloading resources.").build();
373 
374         final Option proxyPort = Option.builder().argName("port").hasArg().longOpt(ARGUMENT.PROXY_PORT)
375                 .desc("The proxy port to use when downloading resources.").build();
376 
377         final Option proxyUsername = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.PROXY_USERNAME)
378                 .desc("The proxy username to use when downloading resources.").build();
379 
380         final Option proxyPassword = Option.builder().argName("pass").hasArg().longOpt(ARGUMENT.PROXY_PASSWORD)
381                 .desc("The proxy password to use when downloading resources.").build();
382 
383         final Option connectionString = Option.builder().argName("connStr").hasArg().longOpt(ARGUMENT.CONNECTION_STRING)
384                 .desc("The connection string to the database.").build();
385 
386         final Option dbUser = Option.builder().argName("user").hasArg().longOpt(ARGUMENT.DB_NAME)
387                 .desc("The username used to connect to the database.").build();
388 
389         final Option dbPassword = Option.builder().argName("password").hasArg().longOpt(ARGUMENT.DB_PASSWORD)
390                 .desc("The password for connecting to the database.").build();
391 
392         final Option dbDriver = Option.builder().argName("driver").hasArg().longOpt(ARGUMENT.DB_DRIVER)
393                 .desc("The database driver name.").build();
394 
395         final Option dbDriverPath = Option.builder().argName("path").hasArg().longOpt(ARGUMENT.DB_DRIVER_PATH)
396                 .desc("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.")
397                 .build();
398 
399         final Option disableJarAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_JAR)
400                 .desc("Disable the Jar Analyzer.").build();
401 
402         final Option disableArchiveAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ARCHIVE)
403                 .desc("Disable the Archive Analyzer.").build();
404 
405         final Option disableNuspecAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NUSPEC)
406                 .desc("Disable the Nuspec Analyzer.").build();
407 
408         final Option disableAssemblyAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_ASSEMBLY)
409                 .desc("Disable the .NET Assembly Analyzer.").build();
410 
411         final Option disablePythonDistributionAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_DIST)
412                 .desc("Disable the Python Distribution Analyzer.").build();
413 
414         final Option disablePythonPackageAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_PY_PKG)
415                 .desc("Disable the Python Package Analyzer.").build();
416 
417         final Option disableComposerAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_COMPOSER)
418                 .desc("Disable the PHP Composer Analyzer.").build();
419 
420         final Option disableAutoconfAnalyzer = Option.builder()
421                 .longOpt(ARGUMENT.DISABLE_AUTOCONF)
422                 .desc("Disable the Autoconf Analyzer.").build();
423 
424         final Option disableOpenSSLAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_OPENSSL)
425                 .desc("Disable the OpenSSL Analyzer.").build();
426         final Option disableCmakeAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CMAKE)
427                 .desc("Disable the Cmake Analyzer.").build();
428 
429         final Option disableCentralAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_CENTRAL)
430                 .desc("Disable the Central Analyzer. If this analyzer is disabled it is likely you also want to disable "
431                         + "the Nexus Analyzer.").build();
432 
433         final Option disableNexusAnalyzer = Option.builder().longOpt(ARGUMENT.DISABLE_NEXUS)
434                 .desc("Disable the Nexus Analyzer.").build();
435 
436         final Option purge = Option.builder().longOpt(ARGUMENT.PURGE_NVD)
437                 .desc("Purges the local NVD data cache")
438                 .build();
439 
440         options.addOption(updateOnly)
441                 .addOption(cve12Base)
442                 .addOption(cve20Base)
443                 .addOption(cve12Modified)
444                 .addOption(cve20Modified)
445                 .addOption(proxyPort)
446                 .addOption(proxyServer)
447                 .addOption(proxyUsername)
448                 .addOption(proxyPassword)
449                 .addOption(connectionTimeout)
450                 .addOption(connectionString)
451                 .addOption(dbUser)
452                 .addOption(data)
453                 .addOption(dbPassword)
454                 .addOption(dbDriver)
455                 .addOption(dbDriverPath)
456                 .addOption(disableJarAnalyzer)
457                 .addOption(disableArchiveAnalyzer)
458                 .addOption(disableAssemblyAnalyzer)
459                 .addOption(pathToBundleAudit)
460                 .addOption(disablePythonDistributionAnalyzer)
461                 .addOption(disableCmakeAnalyzer)
462                 .addOption(disablePythonPackageAnalyzer)
463                 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_RUBYGEMS)
464                         .desc("Disable the Ruby Gemspec Analyzer.").build())
465                 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_BUNDLE_AUDIT)
466                         .desc("Disable the Ruby Bundler-Audit Analyzer.").build())
467                 .addOption(disableAutoconfAnalyzer)
468                 .addOption(disableComposerAnalyzer)
469                 .addOption(disableOpenSSLAnalyzer)
470                 .addOption(disableNuspecAnalyzer)
471                 .addOption(disableCentralAnalyzer)
472                 .addOption(disableNexusAnalyzer)
473                 .addOption(Option.builder().longOpt(ARGUMENT.DISABLE_NODE_JS)
474                         .desc("Disable the Node.js Package Analyzer.").build())
475                 .addOption(nexusUrl)
476                 .addOption(nexusUsesProxy)
477                 .addOption(additionalZipExtensions)
478                 .addOption(pathToMono)
479                 .addOption(pathToBundleAudit)
480                 .addOption(purge);
481     }
482 
483     /**
484      * Adds the deprecated command line options to the given options collection.
485      * These are split out for purposes of not including them in the help
486      * message. We need to add the deprecated options so as not to break
487      * existing scripts.
488      *
489      * @param options a collection of command line arguments
490      * @throws IllegalArgumentException thrown if there is an exception
491      */
492     @SuppressWarnings({"static-access", "deprecation"})
493     private void addDeprecatedOptions(final Options options) throws IllegalArgumentException {
494 
495         final Option proxyServer = Option.builder().argName("url").hasArg().longOpt(ARGUMENT.PROXY_URL)
496                 .desc("The proxy url argument is deprecated, use proxyserver instead.")
497                 .build();
498         final Option appName = Option.builder(ARGUMENT.APP_NAME_SHORT).argName("name").hasArg().longOpt(ARGUMENT.APP_NAME)
499                 .desc("The name of the project being scanned.")
500                 .build();
501 
502         options.addOption(proxyServer);
503         options.addOption(appName);
504     }
505 
506     /**
507      * Determines if the 'version' command line argument was passed in.
508      *
509      * @return whether or not the 'version' command line argument was passed in
510      */
511     public boolean isGetVersion() {
512         return (line != null) && line.hasOption(ARGUMENT.VERSION);
513     }
514 
515     /**
516      * Determines if the 'help' command line argument was passed in.
517      *
518      * @return whether or not the 'help' command line argument was passed in
519      */
520     public boolean isGetHelp() {
521         return (line != null) && line.hasOption(ARGUMENT.HELP);
522     }
523 
524     /**
525      * Determines if the 'scan' command line argument was passed in.
526      *
527      * @return whether or not the 'scan' command line argument was passed in
528      */
529     public boolean isRunScan() {
530         return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN);
531     }
532 
533     /**
534      * Returns the symbolic link depth (how deeply symbolic links will be
535      * followed).
536      *
537      * @return the symbolic link depth
538      */
539     public int getSymLinkDepth() {
540         int value = 0;
541         try {
542             value = Integer.parseInt(line.getOptionValue(ARGUMENT.SYM_LINK_DEPTH, "0"));
543             if (value < 0) {
544                 value = 0;
545             }
546         } catch (NumberFormatException ex) {
547             LOGGER.debug("Symbolic link was not a number");
548         }
549         return value;
550     }
551 
552     /**
553      * Returns true if the disableJar command line argument was specified.
554      *
555      * @return true if the disableJar command line argument was specified;
556      * otherwise false
557      */
558     public boolean isJarDisabled() {
559         return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR);
560     }
561 
562     /**
563      * Returns true if the disableArchive command line argument was specified.
564      *
565      * @return true if the disableArchive command line argument was specified;
566      * otherwise false
567      */
568     public boolean isArchiveDisabled() {
569         return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE);
570     }
571 
572     /**
573      * Returns true if the disableNuspec command line argument was specified.
574      *
575      * @return true if the disableNuspec command line argument was specified;
576      * otherwise false
577      */
578     public boolean isNuspecDisabled() {
579         return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC);
580     }
581 
582     /**
583      * Returns true if the disableAssembly command line argument was specified.
584      *
585      * @return true if the disableAssembly command line argument was specified;
586      * otherwise false
587      */
588     public boolean isAssemblyDisabled() {
589         return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY);
590     }
591 
592     /**
593      * Returns true if the disableBundleAudit command line argument was
594      * specified.
595      *
596      * @return true if the disableBundleAudit command line argument was
597      * specified; otherwise false
598      */
599     public boolean isBundleAuditDisabled() {
600         return (line != null) && line.hasOption(ARGUMENT.DISABLE_BUNDLE_AUDIT);
601     }
602 
603     /**
604      * Returns true if the disablePyDist command line argument was specified.
605      *
606      * @return true if the disablePyDist command line argument was specified;
607      * otherwise false
608      */
609     public boolean isPythonDistributionDisabled() {
610         return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_DIST);
611     }
612 
613     /**
614      * Returns true if the disablePyPkg command line argument was specified.
615      *
616      * @return true if the disablePyPkg command line argument was specified;
617      * otherwise false
618      */
619     public boolean isPythonPackageDisabled() {
620         return (line != null) && line.hasOption(ARGUMENT.DISABLE_PY_PKG);
621     }
622 
623     /**
624      * Returns whether the Ruby gemspec analyzer is disabled.
625      *
626      * @return true if the {@link ARGUMENT#DISABLE_RUBYGEMS} command line
627      * argument was specified; otherwise false
628      */
629     public boolean isRubyGemspecDisabled() {
630         return (null != line) && line.hasOption(ARGUMENT.DISABLE_RUBYGEMS);
631     }
632 
633     /**
634      * Returns true if the disableCmake command line argument was specified.
635      *
636      * @return true if the disableCmake command line argument was specified;
637      * otherwise false
638      */
639     public boolean isCmakeDisabled() {
640         return (line != null) && line.hasOption(ARGUMENT.DISABLE_CMAKE);
641     }
642 
643     /**
644      * Returns true if the disableAutoconf command line argument was specified.
645      *
646      * @return true if the disableAutoconf command line argument was specified;
647      * otherwise false
648      */
649     public boolean isAutoconfDisabled() {
650         return (line != null) && line.hasOption(ARGUMENT.DISABLE_AUTOCONF);
651     }
652 
653     /**
654      * Returns true if the disableComposer command line argument was specified.
655      *
656      * @return true if the disableComposer command line argument was specified;
657      * otherwise false
658      */
659     public boolean isComposerDisabled() {
660         return (line != null) && line.hasOption(ARGUMENT.DISABLE_COMPOSER);
661     }
662 
663     /**
664      * Returns true if the disableNexus command line argument was specified.
665      *
666      * @return true if the disableNexus command line argument was specified;
667      * otherwise false
668      */
669     public boolean isNexusDisabled() {
670         return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS);
671     }
672 
673     /**
674      * Returns true if the disableOpenSSL command line argument was specified.
675      *
676      * @return true if the disableOpenSSL command line argument was specified;
677      * otherwise false
678      */
679     public boolean isOpenSSLDisabled() {
680         return (line != null) && line.hasOption(ARGUMENT.DISABLE_OPENSSL);
681     }
682 
683     /**
684      * Returns true if the disableNodeJS command line argument was specified.
685      *
686      * @return true if the disableNodeJS command line argument was specified;
687      * otherwise false
688      */
689     public boolean isNodeJsDisabled() {
690         return (line != null) && line.hasOption(ARGUMENT.DISABLE_NODE_JS);
691     }
692 
693     /**
694      * Returns true if the disableCentral command line argument was specified.
695      *
696      * @return true if the disableCentral command line argument was specified;
697      * otherwise false
698      */
699     public boolean isCentralDisabled() {
700         return (line != null) && line.hasOption(ARGUMENT.DISABLE_CENTRAL);
701     }
702 
703     /**
704      * Returns the url to the nexus server if one was specified.
705      *
706      * @return the url to the nexus server; if none was specified this will
707      * return null;
708      */
709     public String getNexusUrl() {
710         if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) {
711             return null;
712         } else {
713             return line.getOptionValue(ARGUMENT.NEXUS_URL);
714         }
715     }
716 
717     /**
718      * Returns true if the Nexus Analyzer should use the configured proxy to
719      * connect to Nexus; otherwise false is returned.
720      *
721      * @return true if the Nexus Analyzer should use the configured proxy to
722      * connect to Nexus; otherwise false
723      */
724     public boolean isNexusUsesProxy() {
725         // If they didn't specify whether Nexus needs to use the proxy, we should
726         // still honor the property if it's set.
727         if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) {
728             try {
729                 return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_USES_PROXY);
730             } catch (InvalidSettingException ise) {
731                 return true;
732             }
733         } else {
734             return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY));
735         }
736     }
737 
738     /**
739      * Displays the command line help message to the standard output.
740      */
741     public void printHelp() {
742         final HelpFormatter formatter = new HelpFormatter();
743         final Options options = new Options();
744         addStandardOptions(options);
745         if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) {
746             addAdvancedOptions(options);
747         }
748         final String helpMsg = String.format("%n%s"
749                 + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. "
750                 + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n",
751                 Settings.getString("application.name", "DependencyCheck"),
752                 Settings.getString("application.name", "DependencyCheck"));
753 
754         formatter.printHelp(Settings.getString("application.name", "DependencyCheck"),
755                 helpMsg,
756                 options,
757                 "",
758                 true);
759     }
760 
761     /**
762      * Retrieves the file command line parameter(s) specified for the 'scan'
763      * argument.
764      *
765      * @return the file paths specified on the command line for scan
766      */
767     public String[] getScanFiles() {
768         return line.getOptionValues(ARGUMENT.SCAN);
769     }
770 
771     /**
772      * Retrieves the list of excluded file patterns specified by the 'exclude'
773      * argument.
774      *
775      * @return the excluded file patterns
776      */
777     public String[] getExcludeList() {
778         return line.getOptionValues(ARGUMENT.EXCLUDE);
779     }
780 
781     /**
782      * Returns the directory to write the reports to specified on the command
783      * line.
784      *
785      * @return the path to the reports directory.
786      */
787     public String getReportDirectory() {
788         return line.getOptionValue(ARGUMENT.OUT, ".");
789     }
790 
791     /**
792      * Returns the path to Mono for .NET Assembly analysis on non-windows
793      * systems.
794      *
795      * @return the path to Mono
796      */
797     public String getPathToMono() {
798         return line.getOptionValue(ARGUMENT.PATH_TO_MONO);
799     }
800 
801     /**
802      * Returns the path to bundle-audit for Ruby bundle analysis.
803      *
804      * @return the path to Mono
805      */
806     public String getPathToBundleAudit() {
807         return line.getOptionValue(ARGUMENT.PATH_TO_BUNDLE_AUDIT);
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         return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML");
818     }
819 
820     /**
821      * Returns the application name specified on the command line.
822      *
823      * @return the application name.
824      */
825     public String getProjectName() {
826         final String appName = line.getOptionValue(ARGUMENT.APP_NAME);
827         String name = line.getOptionValue(ARGUMENT.PROJECT);
828         if (name == null && appName != null) {
829             name = appName;
830             LOGGER.warn("The '" + ARGUMENT.APP_NAME + "' argument should no longer be used; use '" + ARGUMENT.PROJECT + "' instead.");
831         }
832         return name;
833     }
834 
835     /**
836      * Returns the base URL for the CVE 1.2 XMl file.
837      *
838      * @return the URL to the CVE 1.2 XML file.
839      */
840     public String getBaseCve12Url() {
841         return line.getOptionValue(ARGUMENT.CVE_BASE_12);
842     }
843 
844     /**
845      * Returns the base URL for the CVE 2.0 XMl file.
846      *
847      * @return the URL to the CVE 2.0 XML file.
848      */
849     public String getBaseCve20Url() {
850         return line.getOptionValue(ARGUMENT.CVE_BASE_20);
851     }
852 
853     /**
854      * Returns the URL for the modified CVE 1.2 XMl file.
855      *
856      * @return the URL to the modified CVE 1.2 XML file.
857      */
858     public String getModifiedCve12Url() {
859         return line.getOptionValue(ARGUMENT.CVE_MOD_12);
860     }
861 
862     /**
863      * Returns the URL for the modified CVE 2.0 XMl file.
864      *
865      * @return the URL to the modified CVE 2.0 XML file.
866      */
867     public String getModifiedCve20Url() {
868         return line.getOptionValue(ARGUMENT.CVE_MOD_20);
869     }
870 
871     /**
872      * Returns the connection timeout.
873      *
874      * @return the connection timeout
875      */
876     public String getConnectionTimeout() {
877         return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT);
878     }
879 
880     /**
881      * Returns the proxy server.
882      *
883      * @return the proxy server
884      */
885     @SuppressWarnings("deprecation")
886     public String getProxyServer() {
887 
888         String server = line.getOptionValue(ARGUMENT.PROXY_SERVER);
889         if (server == null) {
890             server = line.getOptionValue(ARGUMENT.PROXY_URL);
891             if (server != null) {
892                 LOGGER.warn("An old command line argument 'proxyurl' was detected; use proxyserver instead");
893             }
894         }
895         return server;
896     }
897 
898     /**
899      * Returns the proxy port.
900      *
901      * @return the proxy port
902      */
903     public String getProxyPort() {
904         return line.getOptionValue(ARGUMENT.PROXY_PORT);
905     }
906 
907     /**
908      * Returns the proxy username.
909      *
910      * @return the proxy username
911      */
912     public String getProxyUsername() {
913         return line.getOptionValue(ARGUMENT.PROXY_USERNAME);
914     }
915 
916     /**
917      * Returns the proxy password.
918      *
919      * @return the proxy password
920      */
921     public String getProxyPassword() {
922         return line.getOptionValue(ARGUMENT.PROXY_PASSWORD);
923     }
924 
925     /**
926      * Get the value of dataDirectory.
927      *
928      * @return the value of dataDirectory
929      */
930     public String getDataDirectory() {
931         return line.getOptionValue(ARGUMENT.DATA_DIRECTORY);
932     }
933 
934     /**
935      * Returns the properties file specified on the command line.
936      *
937      * @return the properties file specified on the command line
938      */
939     public File getPropertiesFile() {
940         final String path = line.getOptionValue(ARGUMENT.PROP);
941         if (path != null) {
942             return new File(path);
943         }
944         return null;
945     }
946 
947     /**
948      * Returns the path to the verbose log file.
949      *
950      * @return the path to the verbose log file
951      */
952     public String getVerboseLog() {
953         return line.getOptionValue(ARGUMENT.VERBOSE_LOG);
954     }
955 
956     /**
957      * Returns the path to the suppression file.
958      *
959      * @return the path to the suppression file
960      */
961     public String getSuppressionFile() {
962         return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE);
963     }
964 
965     /**
966      * <p>
967      * Prints the manifest information to standard output.</p>
968      * <ul><li>Implementation-Title: ${pom.name}</li>
969      * <li>Implementation-Version: ${pom.version}</li></ul>
970      */
971     public void printVersionInfo() {
972         final String version = String.format("%s version %s",
973                 Settings.getString(Settings.KEYS.APPLICATION_NAME, "dependency-check"),
974                 Settings.getString(Settings.KEYS.APPLICATION_VERSION, "Unknown"));
975         System.out.println(version);
976     }
977 
978     /**
979      * Checks if the auto update feature has been disabled. If it has been
980      * disabled via the command line this will return false.
981      *
982      * @return <code>true</code> if auto-update is allowed; otherwise
983      * <code>false</code>
984      */
985     public boolean isAutoUpdate() {
986         return line != null && !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE);
987     }
988 
989     /**
990      * Checks if the update only flag has been set.
991      *
992      * @return <code>true</code> if the update only flag has been set; otherwise
993      * <code>false</code>.
994      */
995     public boolean isUpdateOnly() {
996         return line != null && line.hasOption(ARGUMENT.UPDATE_ONLY);
997     }
998 
999     /**
1000      * Checks if the purge NVD flag has been set.
1001      *
1002      * @return <code>true</code> if the purge nvd flag has been set; otherwise
1003      * <code>false</code>.
1004      */
1005     public boolean isPurge() {
1006         return line != null && line.hasOption(ARGUMENT.PURGE_NVD);
1007     }
1008 
1009     /**
1010      * Returns the database driver name if specified; otherwise null is
1011      * returned.
1012      *
1013      * @return the database driver name if specified; otherwise null is returned
1014      */
1015     public String getDatabaseDriverName() {
1016         return line.getOptionValue(ARGUMENT.DB_DRIVER);
1017     }
1018 
1019     /**
1020      * Returns the database driver path if specified; otherwise null is
1021      * returned.
1022      *
1023      * @return the database driver name if specified; otherwise null is returned
1024      */
1025     public String getDatabaseDriverPath() {
1026         return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH);
1027     }
1028 
1029     /**
1030      * Returns the database connection string if specified; otherwise null is
1031      * returned.
1032      *
1033      * @return the database connection string if specified; otherwise null is
1034      * returned
1035      */
1036     public String getConnectionString() {
1037         return line.getOptionValue(ARGUMENT.CONNECTION_STRING);
1038     }
1039 
1040     /**
1041      * Returns the database database user name if specified; otherwise null is
1042      * returned.
1043      *
1044      * @return the database database user name if specified; otherwise null is
1045      * returned
1046      */
1047     public String getDatabaseUser() {
1048         return line.getOptionValue(ARGUMENT.DB_NAME);
1049     }
1050 
1051     /**
1052      * Returns the database database password if specified; otherwise null is
1053      * returned.
1054      *
1055      * @return the database database password if specified; otherwise null is
1056      * returned
1057      */
1058     public String getDatabasePassword() {
1059         return line.getOptionValue(ARGUMENT.DB_PASSWORD);
1060     }
1061 
1062     /**
1063      * Returns the additional Extensions if specified; otherwise null is
1064      * returned.
1065      *
1066      * @return the additional Extensions; otherwise null is returned
1067      */
1068     public String getAdditionalZipExtensions() {
1069         return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS);
1070     }
1071 
1072     /**
1073      * Get the value of cveValidForHours.
1074      *
1075      * @return the value of cveValidForHours
1076      */
1077     public Integer getCveValidForHours() {
1078         final String v = line.getOptionValue(ARGUMENT.CVE_VALID_FOR_HOURS);
1079         if (v != null) {
1080             return Integer.parseInt(v);
1081         }
1082         return null;
1083     }
1084 
1085     /**
1086      * Returns true if the experimental analyzers are enabled.
1087      *
1088      * @return true if the experimental analyzers are enabled; otherwise false
1089      */
1090     public boolean isExperimentalEnabled() {
1091         return line.hasOption(ARGUMENT.EXPERIMENTAL);
1092     }
1093 
1094     /**
1095      * A collection of static final strings that represent the possible command
1096      * line arguments.
1097      */
1098     public static class ARGUMENT {
1099 
1100         /**
1101          * The long CLI argument name specifying the directory/file to scan.
1102          */
1103         public static final String SCAN = "scan";
1104         /**
1105          * The short CLI argument name specifying the directory/file to scan.
1106          */
1107         public static final String SCAN_SHORT = "s";
1108         /**
1109          * The long CLI argument name specifying that the CPE/CVE/etc. data
1110          * should not be automatically updated.
1111          */
1112         public static final String DISABLE_AUTO_UPDATE = "noupdate";
1113         /**
1114          * The short CLI argument name specifying that the CPE/CVE/etc. data
1115          * should not be automatically updated.
1116          */
1117         public static final String DISABLE_AUTO_UPDATE_SHORT = "n";
1118         /**
1119          * The long CLI argument name specifying that only the update phase
1120          * should be executed; no scan should be run.
1121          */
1122         public static final String UPDATE_ONLY = "updateonly";
1123         /**
1124          * The long CLI argument name specifying that only the update phase
1125          * should be executed; no scan should be run.
1126          */
1127         public static final String PURGE_NVD = "purge";
1128         /**
1129          * The long CLI argument name specifying the directory to write the
1130          * reports to.
1131          */
1132         public static final String OUT = "out";
1133         /**
1134          * The short CLI argument name specifying the directory to write the
1135          * reports to.
1136          */
1137         public static final String OUT_SHORT = "o";
1138         /**
1139          * The long CLI argument name specifying the output format to write the
1140          * reports to.
1141          */
1142         public static final String OUTPUT_FORMAT = "format";
1143         /**
1144          * The short CLI argument name specifying the output format to write the
1145          * reports to.
1146          */
1147         public static final String OUTPUT_FORMAT_SHORT = "f";
1148         /**
1149          * The long CLI argument name specifying the name of the project to be
1150          * scanned.
1151          */
1152         public static final String PROJECT = "project";
1153         /**
1154          * The long CLI argument name specifying the name of the application to
1155          * be scanned.
1156          *
1157          * @deprecated project should be used instead
1158          */
1159         @Deprecated
1160         public static final String APP_NAME = "app";
1161         /**
1162          * The short CLI argument name specifying the name of the application to
1163          * be scanned.
1164          *
1165          * @deprecated project should be used instead
1166          */
1167         @Deprecated
1168         public static final String APP_NAME_SHORT = "a";
1169         /**
1170          * The long CLI argument name asking for help.
1171          */
1172         public static final String HELP = "help";
1173         /**
1174          * The long CLI argument name asking for advanced help.
1175          */
1176         public static final String ADVANCED_HELP = "advancedHelp";
1177         /**
1178          * The short CLI argument name asking for help.
1179          */
1180         public static final String HELP_SHORT = "h";
1181         /**
1182          * The long CLI argument name asking for the version.
1183          */
1184         public static final String VERSION_SHORT = "v";
1185         /**
1186          * The short CLI argument name asking for the version.
1187          */
1188         public static final String VERSION = "version";
1189         /**
1190          * The CLI argument name indicating the proxy port.
1191          */
1192         public static final String PROXY_PORT = "proxyport";
1193         /**
1194          * The CLI argument name indicating the proxy server.
1195          */
1196         public static final String PROXY_SERVER = "proxyserver";
1197         /**
1198          * The CLI argument name indicating the proxy url.
1199          *
1200          * @deprecated use {@link #PROXY_SERVER} instead
1201          */
1202         @Deprecated
1203         public static final String PROXY_URL = "proxyurl";
1204         /**
1205          * The CLI argument name indicating the proxy username.
1206          */
1207         public static final String PROXY_USERNAME = "proxyuser";
1208         /**
1209          * The CLI argument name indicating the proxy password.
1210          */
1211         public static final String PROXY_PASSWORD = "proxypass";
1212         /**
1213          * The short CLI argument name indicating the connection timeout.
1214          */
1215         public static final String CONNECTION_TIMEOUT_SHORT = "c";
1216         /**
1217          * The CLI argument name indicating the connection timeout.
1218          */
1219         public static final String CONNECTION_TIMEOUT = "connectiontimeout";
1220         /**
1221          * The short CLI argument name for setting the location of an additional
1222          * properties file.
1223          */
1224         public static final String PROP_SHORT = "P";
1225         /**
1226          * The CLI argument name for setting the location of an additional
1227          * properties file.
1228          */
1229         public static final String PROP = "propertyfile";
1230         /**
1231          * The CLI argument name for setting the location of the data directory.
1232          */
1233         public static final String DATA_DIRECTORY = "data";
1234         /**
1235          * The CLI argument name for setting the URL for the CVE Data Files.
1236          */
1237         public static final String CVE_MOD_12 = "cveUrl12Modified";
1238         /**
1239          * The CLI argument name for setting the URL for the CVE Data Files.
1240          */
1241         public static final String CVE_MOD_20 = "cveUrl20Modified";
1242         /**
1243          * The CLI argument name for setting the URL for the CVE Data Files.
1244          */
1245         public static final String CVE_BASE_12 = "cveUrl12Base";
1246         /**
1247          * The CLI argument name for setting the URL for the CVE Data Files.
1248          */
1249         public static final String CVE_BASE_20 = "cveUrl20Base";
1250         /**
1251          * The short CLI argument name for setting the location of the data
1252          * directory.
1253          */
1254         public static final String DATA_DIRECTORY_SHORT = "d";
1255         /**
1256          * The CLI argument name for setting the location of the data directory.
1257          */
1258         public static final String VERBOSE_LOG = "log";
1259         /**
1260          * The short CLI argument name for setting the location of the data
1261          * directory.
1262          */
1263         public static final String VERBOSE_LOG_SHORT = "l";
1264 
1265         /**
1266          * The CLI argument name for setting the depth of symbolic links that
1267          * will be followed.
1268          */
1269         public static final String SYM_LINK_DEPTH = "symLink";
1270         /**
1271          * The CLI argument name for setting the location of the suppression
1272          * file.
1273          */
1274         public static final String SUPPRESSION_FILE = "suppression";
1275         /**
1276          * The CLI argument name for setting the location of the suppression
1277          * file.
1278          */
1279         public static final String CVE_VALID_FOR_HOURS = "cveValidForHours";
1280         /**
1281          * Disables the Jar Analyzer.
1282          */
1283         public static final String DISABLE_JAR = "disableJar";
1284         /**
1285          * Disables the Archive Analyzer.
1286          */
1287         public static final String DISABLE_ARCHIVE = "disableArchive";
1288         /**
1289          * Disables the Python Distribution Analyzer.
1290          */
1291         public static final String DISABLE_PY_DIST = "disablePyDist";
1292         /**
1293          * Disables the Python Package Analyzer.
1294          */
1295         public static final String DISABLE_PY_PKG = "disablePyPkg";
1296         /**
1297          * Disables the Python Package Analyzer.
1298          */
1299         public static final String DISABLE_COMPOSER = "disableComposer";
1300         /**
1301          * Disables the Ruby Gemspec Analyzer.
1302          */
1303         public static final String DISABLE_RUBYGEMS = "disableRubygems";
1304         /**
1305          * Disables the Autoconf Analyzer.
1306          */
1307         public static final String DISABLE_AUTOCONF = "disableAutoconf";
1308         /**
1309          * Disables the Cmake Analyzer.
1310          */
1311         public static final String DISABLE_CMAKE = "disableCmake";
1312         /**
1313          * Disables the Assembly Analyzer.
1314          */
1315         public static final String DISABLE_ASSEMBLY = "disableAssembly";
1316         /**
1317          * Disables the Ruby Bundler Audit Analyzer.
1318          */
1319         public static final String DISABLE_BUNDLE_AUDIT = "disableBundleAudit";
1320         /**
1321          * Disables the Nuspec Analyzer.
1322          */
1323         public static final String DISABLE_NUSPEC = "disableNuspec";
1324         /**
1325          * Disables the Central Analyzer.
1326          */
1327         public static final String DISABLE_CENTRAL = "disableCentral";
1328         /**
1329          * Disables the Nexus Analyzer.
1330          */
1331         public static final String DISABLE_NEXUS = "disableNexus";
1332         /**
1333          * Disables the OpenSSL Analyzer.
1334          */
1335         public static final String DISABLE_OPENSSL = "disableOpenSSL";
1336         /**
1337          * Disables the Node.js Package Analyzer.
1338          */
1339         public static final String DISABLE_NODE_JS = "disableNodeJS";
1340         /**
1341          * The URL of the nexus server.
1342          */
1343         public static final String NEXUS_URL = "nexus";
1344         /**
1345          * Whether or not the defined proxy should be used when connecting to
1346          * Nexus.
1347          */
1348         public static final String NEXUS_USES_PROXY = "nexusUsesProxy";
1349         /**
1350          * The CLI argument name for setting the connection string.
1351          */
1352         public static final String CONNECTION_STRING = "connectionString";
1353         /**
1354          * The CLI argument name for setting the database user name.
1355          */
1356         public static final String DB_NAME = "dbUser";
1357         /**
1358          * The CLI argument name for setting the database password.
1359          */
1360         public static final String DB_PASSWORD = "dbPassword";
1361         /**
1362          * The CLI argument name for setting the database driver name.
1363          */
1364         public static final String DB_DRIVER = "dbDriverName";
1365         /**
1366          * The CLI argument name for setting the path to the database driver; in
1367          * case it is not on the class path.
1368          */
1369         public static final String DB_DRIVER_PATH = "dbDriverPath";
1370         /**
1371          * The CLI argument name for setting the path to mono for .NET Assembly
1372          * analysis on non-windows systems.
1373          */
1374         public static final String PATH_TO_MONO = "mono";
1375         /**
1376          * The CLI argument name for setting extra extensions.
1377          */
1378         public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions";
1379         /**
1380          * Exclude path argument.
1381          */
1382         public static final String EXCLUDE = "exclude";
1383         /**
1384          * The CLI argument name for setting the path to bundle-audit for Ruby
1385          * bundle analysis.
1386          */
1387         public static final String PATH_TO_BUNDLE_AUDIT = "bundleAudit";
1388         /**
1389          * The CLI argument to enable the experimental analyzers.
1390          */
1391         private static final String EXPERIMENTAL = "enableExperimental";
1392     }
1393 }