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