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