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