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