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  import java.util.logging.Logger;
23  import org.apache.commons.cli.CommandLine;
24  import org.apache.commons.cli.CommandLineParser;
25  import org.apache.commons.cli.HelpFormatter;
26  import org.apache.commons.cli.Option;
27  import org.apache.commons.cli.OptionBuilder;
28  import org.apache.commons.cli.OptionGroup;
29  import org.apache.commons.cli.Options;
30  import org.apache.commons.cli.ParseException;
31  import org.apache.commons.cli.PosixParser;
32  import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
33  import org.owasp.dependencycheck.utils.InvalidSettingException;
34  import org.owasp.dependencycheck.utils.Settings;
35  
36  /**
37   * A utility to parse command line arguments for the DependencyCheck.
38   *
39   * @author Jeremy Long <jeremy.long@owasp.org>
40   */
41  public final class CliParser {
42  
43      /**
44       * The logger.
45       */
46      private static final Logger LOGGER = Logger.getLogger(CliParser.class.getName());
47      /**
48       * The command line.
49       */
50      private CommandLine line;
51      /**
52       * Indicates whether the arguments are valid.
53       */
54      private boolean isValid = true;
55  
56      /**
57       * Parses the arguments passed in and captures the results for later use.
58       *
59       * @param args the command line arguments
60       * @throws FileNotFoundException is thrown when a 'file' argument does not point to a file that exists.
61       * @throws ParseException is thrown when a Parse Exception occurs.
62       */
63      public void parse(String[] args) throws FileNotFoundException, ParseException {
64          line = parseArgs(args);
65  
66          if (line != null) {
67              validateArgs();
68          }
69      }
70  
71      /**
72       * Parses the command line arguments.
73       *
74       * @param args the command line arguments
75       * @return the results of parsing the command line arguments
76       * @throws ParseException if the arguments are invalid
77       */
78      private CommandLine parseArgs(String[] args) throws ParseException {
79          final CommandLineParser parser = new PosixParser();
80          final Options options = createCommandLineOptions();
81          return parser.parse(options, args);
82      }
83  
84      /**
85       * Validates that the command line arguments are valid.
86       *
87       * @throws FileNotFoundException if there is a file specified by either the SCAN or CPE command line arguments that
88       * does not exist.
89       * @throws ParseException is thrown if there is an exception parsing the command line.
90       */
91      private void validateArgs() throws FileNotFoundException, ParseException {
92          if (isRunScan()) {
93              validatePathExists(getScanFiles(), ARGUMENT.SCAN);
94              validatePathExists(getReportDirectory(), ARGUMENT.OUT);
95              if (getPathToMono() != null) {
96                  validatePathExists(getPathToMono(), ARGUMENT.PATH_TO_MONO);
97              }
98              if (!line.hasOption(ARGUMENT.APP_NAME)) {
99                  throw new ParseException("Missing 'app' argument; the scan cannot be run without the an application name.");
100             }
101             if (line.hasOption(ARGUMENT.OUTPUT_FORMAT)) {
102                 final String format = line.getOptionValue(ARGUMENT.OUTPUT_FORMAT);
103                 try {
104                     Format.valueOf(format);
105                 } catch (IllegalArgumentException ex) {
106                     final String msg = String.format("An invalid 'format' of '%s' was specified. "
107                             + "Supported output formats are XML, HTML, VULN, or ALL", format);
108                     throw new ParseException(msg);
109                 }
110             }
111         }
112     }
113 
114     /**
115      * Validates whether or not the path(s) points at a file that exists; if the path(s) does not point to an existing
116      * file a FileNotFoundException is thrown.
117      *
118      * @param paths the paths to validate if they exists
119      * @param optType the option being validated (e.g. scan, out, etc.)
120      * @throws FileNotFoundException is thrown if one of the paths being validated does not exist.
121      */
122     private void validatePathExists(String[] paths, String optType) throws FileNotFoundException {
123         for (String path : paths) {
124             validatePathExists(path, optType);
125         }
126     }
127 
128     /**
129      * Validates whether or not the path points at a file that exists; if the path does not point to an existing file a
130      * FileNotFoundException is thrown.
131      *
132      * @param path the paths to validate if they exists
133      * @param argumentName the argument being validated (e.g. scan, out, etc.)
134      * @throws FileNotFoundException is thrown if the path being validated does not exist.
135      */
136     private void validatePathExists(String path, String argumentName) throws FileNotFoundException {
137         if (path == null) {
138             isValid = false;
139             final String msg = String.format("Invalid '%s' argument: null", argumentName);
140             throw new FileNotFoundException(msg);
141         } else if (!path.contains("*") && !path.contains("?")) {
142             final File f = new File(path);
143             if ("o".equals(argumentName.substring(0, 1).toLowerCase()) && !"ALL".equals(this.getReportFormat().toUpperCase())) {
144                 final String checkPath = path.toLowerCase();
145                 if (checkPath.endsWith(".html") || checkPath.endsWith(".xml") || checkPath.endsWith(".htm")) {
146                     if (!f.getParentFile().isDirectory()) {
147                         isValid = false;
148                         final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
149                         throw new FileNotFoundException(msg);
150                     }
151                 }
152             } else {
153                 if (!f.exists()) {
154                     isValid = false;
155                     final String msg = String.format("Invalid '%s' argument: '%s'", argumentName, path);
156                     throw new FileNotFoundException(msg);
157                 }
158             }
159         } else if (path.startsWith("//") || path.startsWith("\\\\")) {
160             isValid = false;
161             final String msg = String.format("Invalid '%s' argument: '%s'%nUnable to scan paths that start with '//'.", argumentName, path);
162             throw new FileNotFoundException(msg);
163         }
164     }
165 
166     /**
167      * Generates an Options collection that is used to parse the command line and to display the help message.
168      *
169      * @return the command line options used for parsing the command line
170      */
171     @SuppressWarnings("static-access")
172     private Options createCommandLineOptions() {
173         final Options options = new Options();
174         addStandardOptions(options);
175         addAdvancedOptions(options);
176         addDeprecatedOptions(options);
177         return options;
178     }
179 
180     /**
181      * Adds the standard command line options to the given options collection.
182      *
183      * @param options a collection of command line arguments
184      * @throws IllegalArgumentException thrown if there is an exception
185      */
186     @SuppressWarnings("static-access")
187     private void addStandardOptions(final Options options) throws IllegalArgumentException {
188         final Option help = new Option(ARGUMENT.HELP_SHORT, ARGUMENT.HELP, false,
189                 "Print this message.");
190 
191         final Option advancedHelp = OptionBuilder.withLongOpt(ARGUMENT.ADVANCED_HELP)
192                 .withDescription("Print the advanced help message.").create();
193 
194         final Option version = new Option(ARGUMENT.VERSION_SHORT, ARGUMENT.VERSION,
195                 false, "Print the version information.");
196 
197         final Option noUpdate = new Option(ARGUMENT.DISABLE_AUTO_UPDATE_SHORT, ARGUMENT.DISABLE_AUTO_UPDATE,
198                 false, "Disables the automatic updating of the CPE data.");
199 
200         final Option appName = OptionBuilder.withArgName("name").hasArg().withLongOpt(ARGUMENT.APP_NAME)
201                 .withDescription("The name of the application being scanned. This is a required argument.")
202                 .create(ARGUMENT.APP_NAME_SHORT);
203 
204         final Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.SCAN)
205                 .withDescription("The path to scan - this option can be specified multiple times. Ant style"
206                         + " paths are supported (e.g. path/**/*.jar).")
207                 .create(ARGUMENT.SCAN_SHORT);
208 
209         final Option excludes = OptionBuilder.withArgName("pattern").hasArg().withLongOpt(ARGUMENT.EXCLUDE)
210                 .withDescription("Specify and exclusion pattern. This option can be specified multiple times"
211                         + " and it accepts Ant style excludsions.")
212                 .create();
213 
214         final Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.PROP)
215                 .withDescription("A property file to load.")
216                 .create(ARGUMENT.PROP_SHORT);
217 
218         final Option out = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.OUT)
219                 .withDescription("The folder to write reports to. This defaults to the current directory. "
220                         + "It is possible to set this to a specific file name if the format argument is not set to ALL.")
221                 .create(ARGUMENT.OUT_SHORT);
222 
223         final Option outputFormat = OptionBuilder.withArgName("format").hasArg().withLongOpt(ARGUMENT.OUTPUT_FORMAT)
224                 .withDescription("The output format to write to (XML, HTML, VULN, ALL). The default is HTML.")
225                 .create(ARGUMENT.OUTPUT_FORMAT_SHORT);
226 
227         final Option verboseLog = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.VERBOSE_LOG)
228                 .withDescription("The file path to write verbose logging information.")
229                 .create(ARGUMENT.VERBOSE_LOG_SHORT);
230 
231         final Option suppressionFile = OptionBuilder.withArgName("file").hasArg().withLongOpt(ARGUMENT.SUPPRESSION_FILE)
232                 .withDescription("The file path to the suppression XML file.")
233                 .create();
234 
235         //This is an option group because it can be specified more then once.
236         final OptionGroup og = new OptionGroup();
237         og.addOption(path);
238 
239         final OptionGroup exog = new OptionGroup();
240         exog.addOption(excludes);
241 
242         options.addOptionGroup(og)
243                 .addOptionGroup(exog)
244                 .addOption(out)
245                 .addOption(outputFormat)
246                 .addOption(appName)
247                 .addOption(version)
248                 .addOption(help)
249                 .addOption(advancedHelp)
250                 .addOption(noUpdate)
251                 .addOption(props)
252                 .addOption(verboseLog)
253                 .addOption(suppressionFile);
254     }
255 
256     /**
257      * Adds the advanced command line options to the given options collection. These are split out for purposes of being
258      * able to display two different help messages.
259      *
260      * @param options a collection of command line arguments
261      * @throws IllegalArgumentException thrown if there is an exception
262      */
263     @SuppressWarnings("static-access")
264     private void addAdvancedOptions(final Options options) throws IllegalArgumentException {
265 
266         final Option data = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DATA_DIRECTORY)
267                 .withDescription("The location of the H2 Database file. This option should generally not be set.")
268                 .create(ARGUMENT.DATA_DIRECTORY_SHORT);
269 
270         final Option connectionTimeout = OptionBuilder.withArgName("timeout").hasArg().withLongOpt(ARGUMENT.CONNECTION_TIMEOUT)
271                 .withDescription("The connection timeout (in milliseconds) to use when downloading resources.")
272                 .create(ARGUMENT.CONNECTION_TIMEOUT_SHORT);
273 
274         final Option proxyServer = OptionBuilder.withArgName("server").hasArg().withLongOpt(ARGUMENT.PROXY_SERVER)
275                 .withDescription("The proxy server to use when downloading resources.")
276                 .create();
277 
278         final Option proxyPort = OptionBuilder.withArgName("port").hasArg().withLongOpt(ARGUMENT.PROXY_PORT)
279                 .withDescription("The proxy port to use when downloading resources.")
280                 .create();
281 
282         final Option proxyUsername = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.PROXY_USERNAME)
283                 .withDescription("The proxy username to use when downloading resources.")
284                 .create();
285 
286         final Option proxyPassword = OptionBuilder.withArgName("pass").hasArg().withLongOpt(ARGUMENT.PROXY_PASSWORD)
287                 .withDescription("The proxy password to use when downloading resources.")
288                 .create();
289 
290         final Option connectionString = OptionBuilder.withArgName("connStr").hasArg().withLongOpt(ARGUMENT.CONNECTION_STRING)
291                 .withDescription("The connection string to the database.")
292                 .create();
293 
294         final Option dbUser = OptionBuilder.withArgName("user").hasArg().withLongOpt(ARGUMENT.DB_NAME)
295                 .withDescription("The username used to connect to the database.")
296                 .create();
297 
298         final Option dbPassword = OptionBuilder.withArgName("password").hasArg().withLongOpt(ARGUMENT.DB_PASSWORD)
299                 .withDescription("The password for connecting to the database.")
300                 .create();
301 
302         final Option dbDriver = OptionBuilder.withArgName("driver").hasArg().withLongOpt(ARGUMENT.DB_DRIVER)
303                 .withDescription("The database driver name.")
304                 .create();
305 
306         final Option dbDriverPath = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.DB_DRIVER_PATH)
307                 .withDescription("The path to the database driver; note, this does not need to be set unless the JAR is outside of the classpath.")
308                 .create();
309 
310         final Option disableJarAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_JAR)
311                 .withDescription("Disable the Jar Analyzer.")
312                 .create();
313         final Option disableArchiveAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ARCHIVE)
314                 .withDescription("Disable the Archive Analyzer.")
315                 .create();
316         final Option disableNuspecAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NUSPEC)
317                 .withDescription("Disable the Nuspec Analyzer.")
318                 .create();
319         final Option disableAssemblyAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_ASSEMBLY)
320                 .withDescription("Disable the .NET Assembly Analyzer.")
321                 .create();
322 
323         final Option disableNexusAnalyzer = OptionBuilder.withLongOpt(ARGUMENT.DISABLE_NEXUS)
324                 .withDescription("Disable the Nexus Analyzer.")
325                 .create();
326 
327         final Option nexusUrl = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.NEXUS_URL)
328                 .withDescription("The url to the Nexus Pro Server. If not set the Nexus Analyzer will be disabled.")
329                 .create();
330 
331         final Option nexusUsesProxy = OptionBuilder.withArgName("true/false").hasArg().withLongOpt(ARGUMENT.NEXUS_USES_PROXY)
332                 .withDescription("Whether or not the configured proxy should be used when connecting to Nexus.")
333                 .create();
334 
335         final Option additionalZipExtensions = OptionBuilder.withArgName("extensions").hasArg()
336                 .withLongOpt(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS)
337                 .withDescription("A comma separated list of additional extensions to be scanned as ZIP files "
338                         + "(ZIP, EAR, WAR are already treated as zip files)")
339                 .create();
340 
341         final Option pathToMono = OptionBuilder.withArgName("path").hasArg().withLongOpt(ARGUMENT.PATH_TO_MONO)
342                 .withDescription("The path to Mono for .NET Assembly analysis on non-windows systems.")
343                 .create();
344 
345         options.addOption(proxyPort)
346                 .addOption(proxyServer)
347                 .addOption(proxyUsername)
348                 .addOption(proxyPassword)
349                 .addOption(connectionTimeout)
350                 .addOption(connectionString)
351                 .addOption(dbUser)
352                 .addOption(data)
353                 .addOption(dbPassword)
354                 .addOption(dbDriver)
355                 .addOption(dbDriverPath)
356                 .addOption(disableJarAnalyzer)
357                 .addOption(disableArchiveAnalyzer)
358                 .addOption(disableAssemblyAnalyzer)
359                 .addOption(disableNuspecAnalyzer)
360                 .addOption(disableNexusAnalyzer)
361                 .addOption(nexusUrl)
362                 .addOption(nexusUsesProxy)
363                 .addOption(additionalZipExtensions)
364                 .addOption(pathToMono);
365     }
366 
367     /**
368      * Adds the deprecated command line options to the given options collection. These are split out for purposes of not
369      * including them in the help message. We need to add the deprecated options so as not to break existing scripts.
370      *
371      * @param options a collection of command line arguments
372      * @throws IllegalArgumentException thrown if there is an exception
373      */
374     @SuppressWarnings("static-access")
375     private void addDeprecatedOptions(final Options options) throws IllegalArgumentException {
376 
377         final Option proxyServer = OptionBuilder.withArgName("url").hasArg().withLongOpt(ARGUMENT.PROXY_URL)
378                 .withDescription("The proxy url argument is deprecated, use proxyserver instead.")
379                 .create();
380 
381         options.addOption(proxyServer);
382     }
383 
384     /**
385      * Determines if the 'version' command line argument was passed in.
386      *
387      * @return whether or not the 'version' command line argument was passed in
388      */
389     public boolean isGetVersion() {
390         return (line != null) && line.hasOption(ARGUMENT.VERSION);
391     }
392 
393     /**
394      * Determines if the 'help' command line argument was passed in.
395      *
396      * @return whether or not the 'help' command line argument was passed in
397      */
398     public boolean isGetHelp() {
399         return (line != null) && line.hasOption(ARGUMENT.HELP);
400     }
401 
402     /**
403      * Determines if the 'scan' command line argument was passed in.
404      *
405      * @return whether or not the 'scan' command line argument was passed in
406      */
407     public boolean isRunScan() {
408         return (line != null) && isValid && line.hasOption(ARGUMENT.SCAN);
409     }
410 
411     /**
412      * Returns true if the disableJar command line argument was specified.
413      *
414      * @return true if the disableJar command line argument was specified; otherwise false
415      */
416     public boolean isJarDisabled() {
417         return (line != null) && line.hasOption(ARGUMENT.DISABLE_JAR);
418     }
419 
420     /**
421      * Returns true if the disableArchive command line argument was specified.
422      *
423      * @return true if the disableArchive command line argument was specified; otherwise false
424      */
425     public boolean isArchiveDisabled() {
426         return (line != null) && line.hasOption(ARGUMENT.DISABLE_ARCHIVE);
427     }
428 
429     /**
430      * Returns true if the disableNuspec command line argument was specified.
431      *
432      * @return true if the disableNuspec command line argument was specified; otherwise false
433      */
434     public boolean isNuspecDisabled() {
435         return (line != null) && line.hasOption(ARGUMENT.DISABLE_NUSPEC);
436     }
437 
438     /**
439      * Returns true if the disableAssembly command line argument was specified.
440      *
441      * @return true if the disableAssembly command line argument was specified; otherwise false
442      */
443     public boolean isAssemblyDisabled() {
444         return (line != null) && line.hasOption(ARGUMENT.DISABLE_ASSEMBLY);
445     }
446 
447     /**
448      * Returns true if the disableNexus command line argument was specified.
449      *
450      * @return true if the disableNexus command line argument was specified; otherwise false
451      */
452     public boolean isNexusDisabled() {
453         return (line != null) && line.hasOption(ARGUMENT.DISABLE_NEXUS);
454     }
455 
456     /**
457      * Returns the url to the nexus server if one was specified.
458      *
459      * @return the url to the nexus server; if none was specified this will return null;
460      */
461     public String getNexusUrl() {
462         if (line == null || !line.hasOption(ARGUMENT.NEXUS_URL)) {
463             return null;
464         } else {
465             return line.getOptionValue(ARGUMENT.NEXUS_URL);
466         }
467     }
468 
469     /**
470      * Returns true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false is
471      * returned.
472      *
473      * @return true if the Nexus Analyzer should use the configured proxy to connect to Nexus; otherwise false
474      */
475     public boolean isNexusUsesProxy() {
476         // If they didn't specify whether Nexus needs to use the proxy, we should
477         // still honor the property if it's set.
478         if (line == null || !line.hasOption(ARGUMENT.NEXUS_USES_PROXY)) {
479             try {
480                 return Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY);
481             } catch (InvalidSettingException ise) {
482                 return true;
483             }
484         } else {
485             return Boolean.parseBoolean(line.getOptionValue(ARGUMENT.NEXUS_USES_PROXY));
486         }
487     }
488 
489     /**
490      * Displays the command line help message to the standard output.
491      */
492     public void printHelp() {
493         final HelpFormatter formatter = new HelpFormatter();
494         final Options options = new Options();
495         addStandardOptions(options);
496         if (line != null && line.hasOption(ARGUMENT.ADVANCED_HELP)) {
497             addAdvancedOptions(options);
498         }
499         final String helpMsg = String.format("%n%s"
500                 + " can be used to identify if there are any known CVE vulnerabilities in libraries utilized by an application. "
501                 + "%s will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.%n%n",
502                 Settings.getString("application.name", "DependencyCheck"),
503                 Settings.getString("application.name", "DependencyCheck"));
504 
505         formatter.printHelp(Settings.getString("application.name", "DependencyCheck"),
506                 helpMsg,
507                 options,
508                 "",
509                 true);
510     }
511 
512     /**
513      * Retrieves the file command line parameter(s) specified for the 'scan' argument.
514      *
515      * @return the file paths specified on the command line for scan
516      */
517     public String[] getScanFiles() {
518         return line.getOptionValues(ARGUMENT.SCAN);
519     }
520 
521     /**
522      * Retrieves the list of excluded file patterns specified by the 'exclude' argument.
523      *
524      * @return the excluded file patterns
525      */
526     public String[] getExcludeList() {
527         return line.getOptionValues(ARGUMENT.EXCLUDE);
528     }
529 
530     /**
531      * Returns the directory to write the reports to specified on the command line.
532      *
533      * @return the path to the reports directory.
534      */
535     public String getReportDirectory() {
536         return line.getOptionValue(ARGUMENT.OUT, ".");
537     }
538 
539     /**
540      * Returns the path to Mono for .NET Assembly analysis on non-windows systems.
541      *
542      * @return the path to Mono
543      */
544     public String getPathToMono() {
545         return line.getOptionValue(ARGUMENT.PATH_TO_MONO);
546     }
547 
548     /**
549      * Returns the output format specified on the command line. Defaults to HTML if no format was specified.
550      *
551      * @return the output format name.
552      */
553     public String getReportFormat() {
554         return line.getOptionValue(ARGUMENT.OUTPUT_FORMAT, "HTML");
555     }
556 
557     /**
558      * Returns the application name specified on the command line.
559      *
560      * @return the application name.
561      */
562     public String getApplicationName() {
563         return line.getOptionValue(ARGUMENT.APP_NAME);
564     }
565 
566     /**
567      * Returns the connection timeout.
568      *
569      * @return the connection timeout
570      */
571     public String getConnectionTimeout() {
572         return line.getOptionValue(ARGUMENT.CONNECTION_TIMEOUT);
573     }
574 
575     /**
576      * Returns the proxy server.
577      *
578      * @return the proxy server
579      */
580     public String getProxyServer() {
581 
582         String server = line.getOptionValue(ARGUMENT.PROXY_SERVER);
583         if (server == null) {
584             server = line.getOptionValue(ARGUMENT.PROXY_URL);
585             if (server != null) {
586                 LOGGER.warning("An old command line argument 'proxyurl' was detected; use proxyserver instead");
587             }
588         }
589         return server;
590     }
591 
592     /**
593      * Returns the proxy port.
594      *
595      * @return the proxy port
596      */
597     public String getProxyPort() {
598         return line.getOptionValue(ARGUMENT.PROXY_PORT);
599     }
600 
601     /**
602      * Returns the proxy username.
603      *
604      * @return the proxy username
605      */
606     public String getProxyUsername() {
607         return line.getOptionValue(ARGUMENT.PROXY_USERNAME);
608     }
609 
610     /**
611      * Returns the proxy password.
612      *
613      * @return the proxy password
614      */
615     public String getProxyPassword() {
616         return line.getOptionValue(ARGUMENT.PROXY_PASSWORD);
617     }
618 
619     /**
620      * Get the value of dataDirectory.
621      *
622      * @return the value of dataDirectory
623      */
624     public String getDataDirectory() {
625         return line.getOptionValue(ARGUMENT.DATA_DIRECTORY);
626     }
627 
628     /**
629      * Returns the properties file specified on the command line.
630      *
631      * @return the properties file specified on the command line
632      */
633     public File getPropertiesFile() {
634         final String path = line.getOptionValue(ARGUMENT.PROP);
635         if (path != null) {
636             return new File(path);
637         }
638         return null;
639     }
640 
641     /**
642      * Returns the path to the verbose log file.
643      *
644      * @return the path to the verbose log file
645      */
646     public String getVerboseLog() {
647         return line.getOptionValue(ARGUMENT.VERBOSE_LOG);
648     }
649 
650     /**
651      * Returns the path to the suppression file.
652      *
653      * @return the path to the suppression file
654      */
655     public String getSuppressionFile() {
656         return line.getOptionValue(ARGUMENT.SUPPRESSION_FILE);
657     }
658 
659     /**
660      * <p>
661      * Prints the manifest information to standard output.</p>
662      * <ul><li>Implementation-Title: ${pom.name}</li>
663      * <li>Implementation-Version: ${pom.version}</li></ul>
664      */
665     public void printVersionInfo() {
666         final String version = String.format("%s version %s",
667                 Settings.getString("application.name", "DependencyCheck"),
668                 Settings.getString("application.version", "Unknown"));
669         System.out.println(version);
670     }
671 
672     /**
673      * Checks if the auto update feature has been disabled. If it has been disabled via the command line this will
674      * return false.
675      *
676      * @return if auto-update is allowed.
677      */
678     public boolean isAutoUpdate() {
679         return (line == null) || !line.hasOption(ARGUMENT.DISABLE_AUTO_UPDATE);
680     }
681 
682     /**
683      * Returns the database driver name if specified; otherwise null is returned.
684      *
685      * @return the database driver name if specified; otherwise null is returned
686      */
687     public String getDatabaseDriverName() {
688         return line.getOptionValue(ARGUMENT.DB_DRIVER);
689     }
690 
691     /**
692      * Returns the database driver path if specified; otherwise null is returned.
693      *
694      * @return the database driver name if specified; otherwise null is returned
695      */
696     public String getDatabaseDriverPath() {
697         return line.getOptionValue(ARGUMENT.DB_DRIVER_PATH);
698     }
699 
700     /**
701      * Returns the database connection string if specified; otherwise null is returned.
702      *
703      * @return the database connection string if specified; otherwise null is returned
704      */
705     public String getConnectionString() {
706         return line.getOptionValue(ARGUMENT.CONNECTION_STRING);
707     }
708 
709     /**
710      * Returns the database database user name if specified; otherwise null is returned.
711      *
712      * @return the database database user name if specified; otherwise null is returned
713      */
714     public String getDatabaseUser() {
715         return line.getOptionValue(ARGUMENT.DB_NAME);
716     }
717 
718     /**
719      * Returns the database database password if specified; otherwise null is returned.
720      *
721      * @return the database database password if specified; otherwise null is returned
722      */
723     public String getDatabasePassword() {
724         return line.getOptionValue(ARGUMENT.DB_PASSWORD);
725     }
726 
727     /**
728      * Returns the additional Extensions if specified; otherwise null is returned.
729      *
730      * @return the additional Extensions; otherwise null is returned
731      */
732     public String getAdditionalZipExtensions() {
733         return line.getOptionValue(ARGUMENT.ADDITIONAL_ZIP_EXTENSIONS);
734     }
735 
736     /**
737      * A collection of static final strings that represent the possible command line arguments.
738      */
739     public static class ARGUMENT {
740 
741         /**
742          * The long CLI argument name specifying the directory/file to scan.
743          */
744         public static final String SCAN = "scan";
745         /**
746          * The short CLI argument name specifying the directory/file to scan.
747          */
748         public static final String SCAN_SHORT = "s";
749         /**
750          * The long CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated.
751          */
752         public static final String DISABLE_AUTO_UPDATE = "noupdate";
753         /**
754          * The short CLI argument name specifying that the CPE/CVE/etc. data should not be automatically updated.
755          */
756         public static final String DISABLE_AUTO_UPDATE_SHORT = "n";
757         /**
758          * The long CLI argument name specifying the directory to write the reports to.
759          */
760         public static final String OUT = "out";
761         /**
762          * The short CLI argument name specifying the directory to write the reports to.
763          */
764         public static final String OUT_SHORT = "o";
765         /**
766          * The long CLI argument name specifying the output format to write the reports to.
767          */
768         public static final String OUTPUT_FORMAT = "format";
769         /**
770          * The short CLI argument name specifying the output format to write the reports to.
771          */
772         public static final String OUTPUT_FORMAT_SHORT = "f";
773         /**
774          * The long CLI argument name specifying the name of the application to be scanned.
775          */
776         public static final String APP_NAME = "app";
777         /**
778          * The short CLI argument name specifying the name of the application to be scanned.
779          */
780         public static final String APP_NAME_SHORT = "a";
781         /**
782          * The long CLI argument name asking for help.
783          */
784         public static final String HELP = "help";
785         /**
786          * The long CLI argument name asking for advanced help.
787          */
788         public static final String ADVANCED_HELP = "advancedHelp";
789         /**
790          * The short CLI argument name asking for help.
791          */
792         public static final String HELP_SHORT = "h";
793         /**
794          * The long CLI argument name asking for the version.
795          */
796         public static final String VERSION_SHORT = "v";
797         /**
798          * The short CLI argument name asking for the version.
799          */
800         public static final String VERSION = "version";
801         /**
802          * The CLI argument name indicating the proxy port.
803          */
804         public static final String PROXY_PORT = "proxyport";
805         /**
806          * The CLI argument name indicating the proxy server.
807          */
808         public static final String PROXY_SERVER = "proxyserver";
809         /**
810          * The CLI argument name indicating the proxy url.
811          *
812          * @deprecated use {@link org.owasp.dependencycheck.cli.CliParser.ArgumentName#PROXY_SERVER} instead
813          */
814         @Deprecated
815         public static final String PROXY_URL = "proxyurl";
816         /**
817          * The CLI argument name indicating the proxy username.
818          */
819         public static final String PROXY_USERNAME = "proxyuser";
820         /**
821          * The CLI argument name indicating the proxy password.
822          */
823         public static final String PROXY_PASSWORD = "proxypass";
824         /**
825          * The short CLI argument name indicating the connection timeout.
826          */
827         public static final String CONNECTION_TIMEOUT_SHORT = "c";
828         /**
829          * The CLI argument name indicating the connection timeout.
830          */
831         public static final String CONNECTION_TIMEOUT = "connectiontimeout";
832         /**
833          * The short CLI argument name for setting the location of an additional properties file.
834          */
835         public static final String PROP_SHORT = "P";
836         /**
837          * The CLI argument name for setting the location of an additional properties file.
838          */
839         public static final String PROP = "propertyfile";
840         /**
841          * The CLI argument name for setting the location of the data directory.
842          */
843         public static final String DATA_DIRECTORY = "data";
844         /**
845          * The short CLI argument name for setting the location of the data directory.
846          */
847         public static final String DATA_DIRECTORY_SHORT = "d";
848         /**
849          * The CLI argument name for setting the location of the data directory.
850          */
851         public static final String VERBOSE_LOG = "log";
852         /**
853          * The short CLI argument name for setting the location of the data directory.
854          */
855         public static final String VERBOSE_LOG_SHORT = "l";
856         /**
857          * The CLI argument name for setting the location of the suppression file.
858          */
859         public static final String SUPPRESSION_FILE = "suppression";
860         /**
861          * Disables the Jar Analyzer.
862          */
863         public static final String DISABLE_JAR = "disableJar";
864         /**
865          * Disables the Archive Analyzer.
866          */
867         public static final String DISABLE_ARCHIVE = "disableArchive";
868         /**
869          * Disables the Assembly Analyzer.
870          */
871         public static final String DISABLE_ASSEMBLY = "disableAssembly";
872         /**
873          * Disables the Nuspec Analyzer.
874          */
875         public static final String DISABLE_NUSPEC = "disableNuspec";
876         /**
877          * Disables the Nexus Analyzer.
878          */
879         public static final String DISABLE_NEXUS = "disableNexus";
880         /**
881          * The URL of the nexus server.
882          */
883         public static final String NEXUS_URL = "nexus";
884         /**
885          * Whether or not the defined proxy should be used when connecting to Nexus.
886          */
887         public static final String NEXUS_USES_PROXY = "nexusUsesProxy";
888         /**
889          * The CLI argument name for setting the connection string.
890          */
891         public static final String CONNECTION_STRING = "connectionString";
892         /**
893          * The CLI argument name for setting the database user name.
894          */
895         public static final String DB_NAME = "dbUser";
896         /**
897          * The CLI argument name for setting the database password.
898          */
899         public static final String DB_PASSWORD = "dbPassword";
900         /**
901          * The CLI argument name for setting the database driver name.
902          */
903         public static final String DB_DRIVER = "dbDriverName";
904         /**
905          * The CLI argument name for setting the path to the database driver; in case it is not on the class path.
906          */
907         public static final String DB_DRIVER_PATH = "dbDriverPath";
908         /**
909          * The CLI argument name for setting the path to mono for .NET Assembly analysis on non-windows systems.
910          */
911         public static final String PATH_TO_MONO = "mono";
912         /**
913          * The CLI argument name for setting extra extensions.
914          */
915         public static final String ADDITIONAL_ZIP_EXTENSIONS = "zipExtensions";
916         /**
917          * Exclude path argument.
918          */
919         public static final String EXCLUDE = "exclude";
920     }
921 }